在这个问题中,我们只考虑小写英文字母(a-z)字符串。
如果字符串从左到右从右到左遍历时具有完全相同的字符序列,则该字符串是回文。例如,以下字符串是回文:
“皮艇”
“codilitytilidoc”
“neveroddoreven”
字符串A是字符串B的字谜,如果它由完全相同的字符组成,但可能是另一种顺序。例如,以下字符串是彼此的字谜:
A =“mary”B =“army”A =“rocketboys”B =“octobersky”A =“codility”B =“codility”
写一个函数
int isAnagramOfPalindrome(String S);
如果字符串s是某些回文的字谜,则返回1,否则返回0.
例如,你的函数应该为参数“dooernedeevrvn”返回1,因为它是回文“anoddoddoreven”的字谜。对于参数“aabcba”,您的函数应返回0。
答案 0 :(得分:12)
'算法'对它来说太大了。
如果每个字符在该组中出现偶数次(可能除了一个字符),您可以从给定的字符集构造回文。
对于任何其他集合,您可以轻松地显示没有回文存在。
两种情况下的证明都很简单,但如果不清楚,请告诉我。
答案 1 :(得分:3)
在回文中,每个角色必须有一个自身的副本,一个“双胞胎”,在字符串的另一边,除了中间字母,可以作为自己的双胞胎。
您寻找的算法将创建一个长度为26的数组,每个小写字母一个,并开始计算字符串中的字符数,将数字n
的数量放在数组的索引n
。然后,它将通过数组并计算奇数的字符数(因为一个字母没有双胞胎)。如果此数字为0或1,则将该单个奇数字母放在中心,并且很容易生成回文。否则,不可能生成一个,因为不存在双胞胎的两个或更多字母,并且它们不能同时位于中心。
答案 2 :(得分:1)
我想出了这个Javascript解决方案。 这个解决方案是基于这样一个前提:当一个字符串是一个回文的字谜时,当且仅当一个字符出现奇数次时才会出现。
function solution(S) {
var retval = 0;
var sorted = S.split('').sort(); // sort the input characters and store in
// a char array
var array = new Array();
for (var i = 0; i < sorted.length; i++) {
// check if the 2 chars are the same, if so copy the 2 chars to the new
// array
// and additionally increment the counter to account for the second char
// position in the loop.
if ((sorted[i] === sorted[i + 1]) && (sorted[i + 1] != undefined)) {
array.push.apply(array, sorted.slice(i, i + 2));
i = i + 1;
}
}
// if the original string array's length is 1 or more than the length of the
// new array's length
if (sorted.length <= array.length + 1) {
retval = 1;
}
//console.log("new array-> " + array);
//console.log("sorted array-> " + sorted);
return retval;
}
答案 3 :(得分:1)
我在java中编写了这段代码。我不认为它会是一个好人^^,
public static int isAnagramOfPalindrome(String str){
ArrayList<Character> a = new ArrayList<Character>();
for(int i = 0; i < str.length(); i++){
if(a.contains(str.charAt(i))){
a.remove((Object)str.charAt(i));
}
else{
a.add(str.charAt(i));
}
}
if(a.size() > 1)
return 0;
return 1;
}
答案 4 :(得分:1)
算法:
计算每个角色的出现次数。
只允许一个出现奇数的字符,因为在回文中,奇数出现的字符的最大数量可以是&#39; 1&#39;。
所有其他字符应该偶数次出现。
如果(2)和(3)失败,则给定的字符串不是回文。
答案 5 :(得分:0)
这增加了给出的其他答案。我们希望跟踪所看到的每个字母的数量。如果我们有一个以上的奇数计数,那么我们将无法形成回文。奇数将在中间,但只有一个奇数可以这样做。
我们可以使用hashmap来跟踪计数。查找hashmap是O(1)所以它很快。我们能够在O(n)中运行整个算法。这是代码:
if __name__ == '__main__':
line = input()
dic = {}
for i in range(len(line)):
ch = line[i]
if ch in dic:
dic[ch] += 1
else:
dic[ch] = 1
chars_whose_count_is_odd = 0
for key, value in dic.items():
if value % 2 == 1:
chars_whose_count_is_odd += 1
if chars_whose_count_is_odd > 1:
print ("NO")
else:
print ("YES")
答案 6 :(得分:0)
我在this question中发布了一个关于复杂性的PHP的简洁解决方案。
class Solution {
// Function to determine if the input string can make a palindrome by rearranging it
static public function isAnagramOfPalindrome($S) {
// here I am counting how many characters have odd number of occurrences
$odds = count(array_filter(count_chars($S, 1), function($var) {
return($var & 1);
}));
// If the string length is odd, then a palindrome would have 1 character with odd number occurrences
// If the string length is even, all characters should have even number of occurrences
return (int)($odds == (strlen($S) & 1));
}
}
echo Solution :: isAnagramOfPalindrome($_POST['input']);
它使用内置的PHP函数(为什么不使用),但您可以自己创建,因为这些函数非常简单。首先,count_chars
函数生成一个命名数组(python中的字典),其中包含出现在字符串中的所有字符及其出现次数。它可以用这样的自定义函数代替:
$count_chars = array();
foreach($S as $char) {
if array_key_exists($char, $count_chars) {
$count_chars[$char]++;
else {
$count_chars[$char] = 1;
}
}
然后,应用具有array_filter
函数的count
来计算出现奇数的字符数:
$odds = 0;
foreach($count_chars as $char) {
$odds += $char % 2;
}
然后你只需在return
中应用比较(在原始函数的注释中解释)。
return ($odds == strlen($char) % 2)
答案 7 :(得分:0)
这在O(n)中运行。对于所有角色而不是一个,必须是均匀的。可选的奇数字符可以是任何奇数。
e.g。 ABABABA
def anagram_of_pali(str):
char_list = list(str)
map = {}
nb_of_odds = 0
for char in char_list:
if char in map:
map[char] += 1
else:
map[char] = 1
for char in map:
if map[char] % 2 != 0:
nb_of_odds += 1
return True if nb_of_odds <= 1 else False
答案 8 :(得分:0)
你只需计算所有字母并检查是否有奇数字母。如果有多个字母带有奇数,则该字符串不满足上述回文条件 此外,由于具有偶数字母的字符串不能具有带奇数的字母,因此不必检查字符串长度是否为偶数。这需要 O(n)时间复杂度:
以下是javascript
中的实施:
function canRearrangeToPalindrome(str)
{
var letterCounts = {};
var letter;
var palindromeSum = 0;
for (var i = 0; i < str.length; i++) {
letter = str[i];
letterCounts[letter] = letterCounts[letter] || 0;
letterCounts[letter]++;
}
for (var letterCount in letterCounts) {
palindromeSum += letterCounts[letterCount] % 2;
}
return palindromeSum < 2;
}
答案 9 :(得分:0)
好吧 - 已经有一段时间了,但是当我在求职面试中被问到这样一个问题时,我需要尝试几行Python。基本思想是,如果有一个字谜是偶数字母的回文,每个字符出现两次(或类似2n次,即计数%2 == 0)。另外,对于奇数个字符,一个字符(中间的一个)可能只出现一次(或不均匀的数字 - 计数%2 == 1)。 我在python中使用了一个集合来获取唯一的字符,然后在条件无法满足后简单地计算和中断循环。示例代码(Python3):
def is_palindrome(s):
letters = set(s)
oddc=0
fail=False
for c in letters:
if s.count(c)%2==1:
oddc = oddc+1
if oddc>0 and len(s)%2==0:
fail=True
break
elif oddc>1:
fail=True
break
return(not fail)
答案 10 :(得分:-1)
def is_anagram_of_palindrome(S):
L = [ 0 for _ in range(26) ]
a = ord('a')
length = 0
for s in S:
length += 1
i = ord(s) - a
L[i] = abs(L[i] - 1)
return length > 0 and sum(L) < 2 and 1 or 0
答案 11 :(得分:-1)
虽然您可以使用给定的技术检测到给定的字符串“S”是候选回文,但它仍然不是很有用。根据给出的实现,
isAnagramOfPalindrome(“rrss”)将返回true但没有实际的回文因为:
回文是一个单词,短语,数字或其他符号或元素序列,其含义可以在正向或反向方向上以相同的方式解释。 (维基百科)
而Rssr或Srrs不是可解释的实际单词或短语。与它的字谜相同。 Aarrdd不是雷达的字谜,因为它不可解释。
因此,给出的解决方案必须通过针对输入的启发式检查来增强,以查看它是否是一个单词,然后验证(通过给出的实现),它完全可以进行回收。然后用n / 2通过收集的桶进行启发式搜索!排列搜索,如果这些是实际的回文而不是垃圾。搜索只有n / 2!而不是n!因为你计算每个重复字母的所有排列,然后你镜像它们(除了可能添加单数枢轴字母)以创建所有可能的回文。
我不同意算法太大了,因为这种搜索可以纯粹递归地进行,或者使用动态编程(对于出现大于2的字母的单词)并且非常简单。
答案 12 :(得分:-1)
以下是一些代码:这与描述算法的最佳答案相同。
1 #include<iostream>
2 #include<string>
3 #include<vector>
4 #include<stack>
5
6 using namespace std;
7
8 bool fun(string in)
9 {
10 int len=in.size();
11 int myints[len ];
12
13 for(int i=0; i<len; i++)
14 {
15 myints[i]= in.at(i);
16 }
17 vector<char> input(myints, myints+len);
18 sort(input.begin(), input.end());
19
20 stack<int> ret;
21
22 for(int i=0; i<len; i++)
23 {
24 if(!ret.empty() && ret.top()==input.at(i))
25 {
26 ret.pop();
27 }
28 else{
29 ret.push(input.at(i));
30 }
31 }
32
33 return ret.size()<=1;
34
35 }
36
37 int main()
38 {
39 string input;
40 cout<<"Enter word/number"<<endl;
41 cin>>input;
42 cout<<fun(input)<<endl;
43
44 return 0;
45 }