使用给定的字符串字符查找两个唯一的回文字符串
在此问题中,我们将使用给定字符串的字符构造两个回文字符串。
我们可以使用字符的频率来解决问题。只有当两个字符的频率都是偶数,或者任何字符的频率为偶数而其他字符的频率为奇数时,我们才能构造两个新的回文字符串。
问题陈述 - 我们给出了一个字符串 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 构造函数创建一个字符串。之后,我们可以在需要时从两个字符串中提取特定长度的子字符串。