使用给定的字符串字符查找两个唯一的回文字符串

data structurec++server side programmingprogramming更新于 2025/5/2 10:37:17

在此问题中,我们将使用给定字符串的字符构造两个回文字符串。

我们可以使用字符的频率来解决问题。只有当两个字符的频率都是偶数,或者任何字符的频率为偶数而其他字符的频率为奇数时,我们才能构造两个新的回文字符串。

问题陈述 - 我们给出了一个字符串 alpha,其中包含两个不同的字符,大小等于 N。我们需要使用 alpha 的字符构造两个回文字符串,这些字符与给定的字符串 alpha 不同。

示例

在增加给定大小的每个前缀的每个字符后,结果字符串为"gffe"。

输入

alpha = "aaabbabbabb"

输出

bbbaaaaabbb, aabbbabbbaa

解释

"bbbaaaaabbb"和"aabbbabbbaa"是我们从给定字符串构造的不同回文字符串。

输入 

alpha = "aabbb"

输出 

abbba, babab

输入 

alpha = "aaabbabbabb"

输出 

bbbaaaaabbb, aabbbabbbaa

解释

两个输出字符串都是由给定字符的字符串构造的新回文字符串。

输入 

alpha = "aaabbb";

输出 

'不可能。'

解释

不可能从给定的字符串构造两个不同的回文字符串。

方法 1

如果两个字符的频率都是奇数,则不可能构造两个新的回文字符串。例如,在'aaabbb'字符串中,'a'和'b'出现了 3 次。因此,我们无法构造任何单个回文字符串。

如果任何单个字符的频率为偶数,我们总是可以构造两个不同的回文字符串。

  • 对于奇偶字符频率:从"aabbb"中,我们可以构造"abbba"和"babab"字符串。

  • 对于偶偶字符频率:从"aabb"中,我们可以构造"abba"和"baab"类型的字符串。

算法

  • 步骤 1 - 定义"freq"映射来存储两个字符的频率,并遍历字符串以计算每个字符的频率。

  • 步骤 2 - 定义"temp1"和"temp2"存储两个字符,定义"freq1"和"freq2"变量来存储每个字符的频率。

  • 步骤 3 - 遍历映射,如果 flag == 1,则将键分配给"temp1",将值分配给"freq1"。另外,初始化"temp2"和"freq2"字符。

  • 步骤 4 - 如果"freq1"和"freq2"均为 1 或奇数,则打印"不可能",因为我们无法使用字符串字符构造两个回文字符串。

  • 步骤 5 - 如果 freq1 和 freq2 为偶数,请按照以下步骤操作。

  • 步骤 5.1 - 我们需要打印第一个回文字符串。因此,打印 temp1 字符 'freq1/2' 次,打印 'temp2' 字符 'freq2' 次,并再次打印 temp1 字符 'freq1/2' 次。

  • 步骤 5.2 - 对于第二个字符串,打印 temp2 字符 'freq2/2' 次,打印 'temp1' 字符 'freq1' 次,并再次打印 temp2 字符 'freq2/2' 次。

  • 步骤 6 - 如果 freq1 和 freq2 中任何一个为奇数,请按照以下步骤操作。

  • 步骤 6.1 - 对于第一个字符串,如果 freq1 为偶数,则打印 temp1 freq1/2 次,打印 temp2 freq2 次,并打印 temp1 freq2/2 次。否则,如果 freq2 为偶数,则打印 freq2/2 次 temp2、打印 freq1 次 temp1 和打印 freq1/2 次 temp2

  • 步骤 6.2 - 对于第二个字符串,如果 freq1 为偶数,则打印 freq2/2 次 temp2、打印 freq1/2 次 temp1、打印单个 temp2 字符以放置在字符串中间、打印 freq1/2 个 temp1 字符和打印 freq2/2 个 temp2 字符。

  • 步骤 6.3 - 否则,如果 freq1 为奇数,则打印 freq2/2 次 temp1、打印 freq2/2 次 temp2、打印单个 temp1 字符以放置在字符串中间、打印 freq2/2 个 temp2 字符和打印 freq1/2 个 temp1 字符。

示例

#include <bits/stdc++.h>
using namespace std;
void find2Palindromes(string alpha) {
    // 存储字符的频率
    map<char, int> freq;
    
    // 计算每个字符的频率
    for (int p = 0; p < alpha.size(); p++) {
        freq[alpha[p]] += 1;
    }
    char temp1 = ' ', temp2 = ' ';
    int fre1 = 0, freq2 = 0;
    int flag = 1;
    
    // 遍历 map
   for (auto ch : freq) {
   
        // 获取第一个字符的频率
        if (flag == 1) {
            temp1 = ch.first;
            fre1 = ch.second;
            flag++;
        }
        // 获取第二个字符的频率
        else {
         temp2 = ch.first;
         freq2 = ch.second;
        }
   }
   // 检查两个回文字符串是否有可能
   if ((fre1 == 1 || freq2 == 1) || (fre1 % 2 == 1) && (freq2 % 2 == 1)) {
      cout << "not possible";
      cout << endl;
   }
   
   // 情况 1 - 两者都是偶数
   else if (fre1 % 2 == 0 && freq2 % 2 == 0) {
    // 打印一半 temp1
    for (int p = 1; p <= fre1 / 2; p++)
    cout << temp1;
    
    // 打印 temp2
    for (int p = 1; p <= freq2; p++)
    cout << temp2;
    
    // 打印一半 temp1
    for (int p = 1; p <= fre1 / 2; p++)
    cout << temp1;
    cout << " ";
    
    // 第二个回文字符串
    for (int p = 1; p <= freq2 / 2; p++)
     cout << temp2;
    for (int p = 1; p <= fre1; p++)
     cout << temp1;
    for (int p = 1; p <= freq2 / 2; p++)
     cout << temp2;
   }
   
   // 情况 2 - 一个是偶数,一个是奇数
   else if (fre1 % 2 != 0 || freq2 % 2 != 0) {
   
      // 打印第一个字符串
      if (fre1 % 2 == 0) {
         for (int p = 1; p <= fre1 / 2; p++)
            cout << temp1;
         for (int p = 1; p <= freq2; p++)
            cout << temp2;
         for (int p = 1; p <= fre1 / 2; p++)
            cout << temp1;
         cout << " ";
      } else {
         for (int p = 1; p <= freq2 / 2; p++)
            cout << temp2;
         for (int p = 1; p <= fre1; p++)
            cout << temp1;
         for (int p = 1; p <= freq2 / 2; p++)
            cout << temp2;
         cout << " ";
      }

      // 打印第二个字符串
      if (fre1 % 2 == 0) {
         for (int p = 1; p <= freq2 / 2; p++)
            cout << temp2;
         for (int p = 1; p <= fre1 / 2; p++)
            cout << temp1;
         cout << temp2;
         for (int p = 1; p <= fre1 / 2; p++)
            cout << temp1;
         for (int p = 1; p <= freq2 / 2; p++)
         cout << temp2;
      } else {
         for (int p = 1; p <= fre1 / 2; p++)
            cout << temp1;
         for (int p = 1; p <= freq2 / 2; p++)
            cout << temp2;
         cout << temp1;
         for (int p = 1; p <= freq2 / 2; p++)
            cout << temp2;
         for (int p = 1; p <= fre1 / 2; p++)
            cout << temp1;
      }
   }
}
int main() {
   string alpha = "aaabbabbabb";
   cout << "The original String is - " << alpha << endl << "Palindrome Strings are - ";
   find2Palindromes(alpha);
}

输出

The original String is - aaabbabbabb
Palindrome Strings are - bbbaaaaabbb aabbbabbbaa

时间复杂度 – 遍历字符串多次,复杂度为 O(N)。

空间复杂度 – 因为我们打印回文字符串时不使用额外空间,所以复杂度为 O(1)。

我们可以通过将第一个字符放在第一个字符串的中间,将第二个字符放在第二个字符串的中间,从给定的字符串创建两个不同的回文字符串。

程序员可以用 substr() 方法替换 for 循环以缩短代码。首先,我们可以使用包含频率 1 次的临时 1 个字符和频率 2 次的临时 2 个字符的 String 构造函数创建一个字符串。之后,我们可以在需要时从两个字符串中提取特定长度的子字符串。


相关文章