Inputs : I.1) A string of characters
Outputs: O.1) Total number of palindromes found
O.2) Palindromes output on standard output
Note : duplicate palindromes are not allowed
output need not be sorted
single characters are a palindrome.
我通过回溯解决了上述问题,但是它为一个大输入字符串提供了TLE。因此,如果解决方案避免递归将是有益的。
TLE的输入是: - amitabhbacchan
这是我的实施:
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int isSafe(int *a, int i) {
if (a[i] == 0) {
return 1;
}
else {
return 0;
}
}
int isPalin(string b) {
if (b.length() == 0) {
return 0;
}
if (b.length() == 1) {
return 1;
}
string c = b;
std::reverse(c.begin(), c.end());
if (c == b) {
return 1;
}
else {
return 0;
}
}
void palindrome(string a, string b, int *vec, std::set<string>&res) {
if (isPalin(b)) {
if (res.find(b) != res.end()) {
return;
}
res.insert(b);
}
for (int i = 0; i < a.length(); i++) {
if (isSafe(vec, i)) {
b.push_back(a[i]);
vec[i] = 1;
palindrome(a, b, vec, res);
b.pop_back();
vec[i] = 0;
}
}
}
int main(void) {
string a = "ababcdef";
string c = "";
int *vec;
std::set<string>res;
vec = (int*)malloc(a.length()*sizeof(int));
for (int i = 0; i < a.length(); i++) {
vec[i] = 0;
}
palindrome(a, c, vec, res);
std::set<string>::iterator it;
for (it = res.begin(); it != res.end(); it++) {
cout << *it << endl;
}
return 0;
}
答案 0 :(得分:1)
这里的基本问题是你非常低效地产生回文。特别是,您试图生成输入的每个可能的排列,然后检查每个输入是否是回文。
而不是那样,考虑字符串的基本要求是回文(中间的所有字符都与中间的字符相同,并且与中间的字符相反)。因此,除了奇数回文的中间字符之外,回文中的每个其他字符必须偶数次出现。
我首先将字符分成两组:偶数出现和奇数出现。偶数次出现的字符只插入工作集中的一半。也就是说,在输入中给出(例如)aabbccde
,您可以将其分成两部分,一部分包含abc
,另一部分包含de
。
然后,您可以通过生成abc
(以及ab
,ac
和bc
)的所有排列来生成您的回文,您可以按顺序输出,然后输出相反的顺序设置相同(例如,abc
后跟cba
给出abccba
)。然后,对于其中每一个,您可以在中间插入另一个字符中的一个字符,这样您就可以获得abcdcba
和abcecba
)。然后重新排列这些输入以获取(例如)acb
并重复该过程以获得acbbca
,acbdbca
和acbebca
。
生成&#34;偶数&#34;的所有排列的一种方法输入为std::next_permutation
。
请注意,这样您就不会花时间产生许多不属于回文的安排。您事先知道,您生成的每个结果将成为回文。