回文分解算法

时间:2017-03-02 06:15:42

标签: java algorithm time-complexity palindrome

  

给定字符串s,分区s使得分区的每个子字符串都是回文。   返回s的所有可能的回文分区。

我写了一个逻辑来返回一个字符串的回文分解,我很难驾驭它的时间复杂性。它在循环中的递归调用

  

使用的逻辑是迭代从第一个字符开始的每个子字符串,然后一旦我们找到回文,我们从剩余的portition开始检查下一个子字符串。我们递归地说这个

在这种情况下,任何人都可以建议最好的方法来推动这种情况

public class Solution {
public List<List<String>> partition(String s) {
    List<List<String>> result = new ArrayList<List<String>>();
    List<String> palindromePartition = new ArrayList<String>();
    int start=0;

    decompose(s,0,palindromePartition,result);
    return result;

}

private void decompose(String input,int startIndex,List<String> palindromePartition,List<List<String>> result) {
    if(startIndex==input.length())
        {
            ArrayList<String> partitionResult = new ArrayList<String>(palindromePartition);
            result.add(partitionResult);
            return;
        }

    for(int i=startIndex+1;i<=input.length();i++){
            if(isPalindrome(input.substring(startIndex,i))){
               palindromePartition.add(input.substring(startIndex,i));
               decompose(input,i,palindromePartition,result);
               palindromePartition.remove(palindromePartition.size()-1);

            }

    }

}

private boolean isPalindrome(String input){
    int left=0;
    int right=input.length()-1;
    while(right>left){
            if(input.charAt(left)!=input.charAt(right))
                return false;
            left++;
            right--;
    }
    return true;
}

1 个答案:

答案 0 :(得分:0)

首先,请查看您的private boolean isPalindrome(String input){ int left=0; int right=input.length()-1; while(right>left){ if(input.charAt(left)!=input.charAt(right)) return false; left++; right--; } return true; } 方法:

decompose()

此方法查看字符串中的第一个和最后一个字符,并对它们进行比较。这具有O(n / 2)的时间复杂度,因为它必须循环输入的一半长度以执行它需要做的事情。这渐渐变为O(n),因为你忽略了Big-O表示法的常数项。

接下来,查看您的for(int i=startIndex+1;i<=input.length();i++){ if(isPalindrome(input.substring(startIndex,i))){ palindromePartition.add(input.substring(startIndex,i)); decompose(input,i,palindromePartition,result); palindromePartition.remove(palindromePartition.size()-1); } } 方法。这些线是导致时间复杂性的重要因素:

isPalendrome()

在我们包含递归之前,请查看循环和if条件的作用。它们逐个字符地循环输入字符串,并在每个连续的子字符串上调用isPalendrome()函数。如果没有子串内的递归调用,那么它具有时间复杂度O(n ^ 2),因为您调用decompose()方法(时间复杂度O(n))n次。因此,n*(n-1)*(n-2)*.....的每个非递归调用都具有时间复杂度O(n ^ 2)。

添加递归,最坏的情况变得非常糟糕。如果它每次调用自身,复杂度将为n*(n-1)*(n-2)*.....,简化为O(n!)。我通过观察if条件每次都是真的会发生什么来导出{{1}}作为最坏的情况。这意味着对于for循环的每次迭代,你都会调用该函数,并且每次在该调用上,你每次都会再次调用该函数,并且这会一直向下和向下调整,直到你遇到基本情况为止。这在数学上表示的是简化为O(n!)的序列,然后必须乘以n ^ 2。然而,这渐近地简化为O(n!)。最好的情况是O(n ^ 2),这是没有回文时,平均情况将更接近O(n ^ n),因为你可能会经常处理单词中的回文。