以下代码的最佳解决方案可减少运行时间

时间:2015-01-15 19:00:37

标签: java optimization

以下代码用于获取字符串输入并查找其任何排列是否为回文。 代码花了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));
            }
        }
    }
}

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}

  • 对于每个偶数字母,连接这些字母的一半&#39;数字,以任何顺序,例如acr
  • 在中间添加奇数字母,如果有的话,按照计算的频率添加:acr e
  • 最后,再按相反顺序添加第一部分:acr e rca

(当然,racecar本身已经是一个回文,但这并不重要;它更容易找到一个真正的回文词,而不是一个回文置换词。)


最后,请注意代码的复杂性 not O(n)(假设 n 是字符串的长度) 。您正在生成所有排列,因此仅此 O(n!),因为有 n!排列。