以下代码用于获取字符串输入并查找其任何排列是否为回文。 代码花了o(n)时间。我希望有更好的解决方案。
public class Solution {
public static void main(String[] args) {
Scanner myScan = new Scanner(System.in);
String str = myScan.nextLine();
String a = "NO";
permutation("", str);
System.out.println(a);
// Assign ans a value of YES or NO, depending on whether or not inputString satisfies the required condition
myScan.close();
}
private static void permutation(String prefix, String str) {
int n = str.length();
String an = "NO";
if (n == 0) {
System.out.println(prefix);
StringBuffer sb = new StringBuffer(prefix).reverse();
String str1 = sb.toString();
if (prefix.equals(str1)) {
an = "YES";
System.out.println(an);
System.exit(0);
}
} else {
for (int i = 0; i < n; i++) {
permutation(prefix + str.charAt(i),
str.substring(0, i) + str.substring(i + 1));
}
}
}
}
答案 0 :(得分:2)
(这看起来有点像家庭作业,或Java初学者的私人练习,所以我不想给你完整的代码,只是想法或算法,所以你可以想出实际实现自己。)
无需枚举所有排列,看看其中一个是否是回文。您需要做的就是计算单词中的所有字母,看看最多只有一个字母是否有奇数出现。以回文racecar
为例。它可以看作有三个部分:rac e car
。第一和第三部分中的字母是相同的,因此每个字母必须具有偶数。第二部分只有一种字母,但它可以重复多次。
所以,基本算法是这样的:
map
,用于计算字母数,例如Java中的HashMap<String, Integer>
word
中的每个字符,将map
中的计数增加一个int odd_letters
map
中的每个字符,检查其计数是否为奇数,如果是,则将odd_letters
计数器增加一个odd_letters
计数器小于或等于1,则返回true
,否则返回false
如果你还需要知道实际的回文排列,如果有,你可以很容易地从计数图中构建一个。
我们说的是racecar
。计数为{a: 2, c: 2, e: 1, r: 2}
acr
acr e
acr e rca
(当然,racecar
本身已经是一个回文,但这并不重要;它更容易找到一个真正的回文词,而不是一个回文置换词。)
最后,请注意代码的复杂性 not O(n)(假设 n 是字符串的长度) 。您正在生成所有排列,因此仅此 O(n!),因为有 n!排列。