以下代码减少 运行 时间的最佳解决方案
Optimal Solution for the following code to reduce running time
以下代码用于获取字符串输入并查找其排列是否为回文。
该代码需要 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));
}
}
}
}
(这看起来有点像家庭作业,或者 Java 初学者的私人练习,所以我不想给你完整的代码,而只是给你想法或算法,这样你就可以想出自己实际执行。)
没必要把全部的排列都枚举出来,看看其中一个是不是回文。您需要做的就是统计单词中所有的个字母,看看是否有至多一个字母的出现次数为奇数.以回文 racecar
为例。它可以被看作具有三个部分:rac e car
。第一部分和第三部分中的字母相同,因此这些字母中的每一个都必须是偶数。第二部分只有一种字母,但可以重复任意次数。
所以,基本算法是这样的:
- 创建一个字典,
map
,用于计算字母,例如HashMap<String, Integer>
在 Java
- 对于
word
中的每个单独字符,将其在 map
中的计数增加一个
- 为奇数字母创建一个计数器,例如
int odd_letters
- 对于
map
中的每个字符,检查其计数是否为奇数,如果是,则将odd_letters
计数器加一
- 如果
odd_letters
计数器小于或等于1,returntrue
,否则returnfalse
如果你还需要知道实际的回文排列,如果有的话,你可以很容易地从计数图中构造一个。
假设我们的单词是 racecar
。计数为 {a: 2, c: 2, e: 1, r: 2}
- 对于每个偶数字母,以任意顺序连接这些字母数字的一半,例如
acr
- 在中间添加奇数字母(如果有的话),与计算的次数相同:
acr e
- 最后,再次添加第一部分,顺序相反:
acr e rca
(当然,racecar
本身已经是一个回文,但这没关系;找到一个真正的回文词比找到一个回文排列的词更容易。)
最后,请注意你的代码的复杂度是不是O(n)(假设n 是字符串的长度)。您正在生成所有排列,因此仅此一项就必须至少是 O(n!),因为有 n! 个排列。
以下代码用于获取字符串输入并查找其排列是否为回文。 该代码需要 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));
}
}
}
}
(这看起来有点像家庭作业,或者 Java 初学者的私人练习,所以我不想给你完整的代码,而只是给你想法或算法,这样你就可以想出自己实际执行。)
没必要把全部的排列都枚举出来,看看其中一个是不是回文。您需要做的就是统计单词中所有的个字母,看看是否有至多一个字母的出现次数为奇数.以回文 racecar
为例。它可以被看作具有三个部分:rac e car
。第一部分和第三部分中的字母相同,因此这些字母中的每一个都必须是偶数。第二部分只有一种字母,但可以重复任意次数。
所以,基本算法是这样的:
- 创建一个字典,
map
,用于计算字母,例如HashMap<String, Integer>
在 Java - 对于
word
中的每个单独字符,将其在map
中的计数增加一个 - 为奇数字母创建一个计数器,例如
int odd_letters
- 对于
map
中的每个字符,检查其计数是否为奇数,如果是,则将odd_letters
计数器加一 - 如果
odd_letters
计数器小于或等于1,returntrue
,否则returnfalse
如果你还需要知道实际的回文排列,如果有的话,你可以很容易地从计数图中构造一个。
假设我们的单词是 racecar
。计数为 {a: 2, c: 2, e: 1, r: 2}
- 对于每个偶数字母,以任意顺序连接这些字母数字的一半,例如
acr
- 在中间添加奇数字母(如果有的话),与计算的次数相同:
acr e
- 最后,再次添加第一部分,顺序相反:
acr e rca
(当然,racecar
本身已经是一个回文,但这没关系;找到一个真正的回文词比找到一个回文排列的词更容易。)
最后,请注意你的代码的复杂度是不是O(n)(假设n 是字符串的长度)。您正在生成所有排列,因此仅此一项就必须至少是 O(n!),因为有 n! 个排列。