C++ 找出使用给定字符串字符的两个唯一回文字符串

C++ 找出使用给定字符串字符的两个唯一回文字符串

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

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

问题描述 - 我们有一个包含两个不同字符的字符串alpha,大小为N。我们需要使用alpha的字符构造两个回文字符串,这些回文字符串与给定的字符串alpha不相同。

示例

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

输入

alpha = "aaabbabbabb"

输出

bbbaaaaabbb, aabbbabbbaa

解释

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

输入

alpha = "aabbb"

输出

abbba, babab

输入

alpha = "aaabbabbabb"

输出

bbbaaaaabbb, aabbbabbbaa

解释

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

输入

alpha = "aaabbb";

输出

‘Not possible.’

解释

无法从给定字符串构建两个不同的回文字符串。

方法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或奇数,则打印 ‘not possible’,因为我们无法使用字符串字符构建两个回文字符串。

  • 步骤 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 是偶数,则打印 ‘temp2’ 字符 ‘freq2/2’ 次,打印 ‘temp1’ 字符 ‘freq1’ 次,然后打印 ‘temp2’ 字符 ‘freq1/2’ 次。

  • 步骤 6.2 − 对于第二个字符串,如果 freq1 是偶数,则打印 ‘temp2’ 字符 ‘freq2/2’ 次,打印 ‘temp1’ 字符 ‘freq1/2’ 次,单个 ‘temp2’ 字符放在字符串中间,然后打印 freq1/2 个 ‘temp1’ 字符和 freq2/2 个 ‘temp2’ 字符。

  • 步骤 6.3 − 否则,如果 freq1 是奇数,则打印 ‘temp1’ 字符 ‘freq2/2’ 次,打印 ‘temp2’ 字符 ‘freq2/2’ 次,单个 ‘temp1’ 字符放在字符串中间,然后打印 freq2/2 个 ‘temp2’ 字符和 freq1/2 个 ‘temp1’ 字符。

示例

#include <bits/stdc++.h>
using namespace std;
void find2Palindromes(string alpha) {
   // To store the frequency of characters
   map<char, int> freq;

   // Calculating the frequency of each character
   for (int p = 0; p < alpha.size(); p++) {
      freq[alpha[p]] += 1;
   }
   char temp1 = ' ', temp2 = ' ';
   int fre1 = 0, freq2 = 0;
   int flag = 1;

   // Traverse the map
   for (auto ch : freq) {

      // Get the frequency of the first character
      if (flag == 1) {
         temp1 = ch.first;
         fre1 = ch.second;
         flag++;
      }
      // Get the frequency of the second character
      else {
         temp2 = ch.first;
         freq2 = ch.second;
      }
   }
   // Check whether two palindrome strings are possible
   if ((fre1 == 1 || freq2 == 1) || (fre1 % 2 == 1) && (freq2 % 2 == 1)) {
      cout << "not possible";
      cout << endl;
   }

   // Case 1 - Both are even
   else if (fre1 % 2 == 0 && freq2 % 2 == 0) {
      // Print half temp1
      for (int p = 1; p <= fre1 / 2; p++)
      cout << temp1;

      // Print temp2
      for (int p = 1; p <= freq2; p++)
      cout << temp2;

      // Print half temp1
      for (int p = 1; p <= fre1 / 2; p++)
      cout << temp1;
      cout << " ";

      // Second palindrome string
      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;
   }

   // Case 2 - One is even, and one is odd
   else if (fre1 % 2 != 0 || freq2 % 2 != 0) {

      // Print the first string
      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 << " ";
      }

      // Print the second string
      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循环来缩短代码。首先,我们可以使用包含freq1次temp1字符和freq2次temp2字符的String构造函数创建一个字符串。然后,在我们需要的时候,我们可以从两个字符串中提取特定长度的子字符串。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程