-1

Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s.

I wrote a logic to return palindromic decompositions of a string, I am having hard time in driving the time complexity of this . Its recursive call inside for loop

Logic used is to iterate over each substring starting with first character, then once we find palindrome , we check the next substring starting from the remaining portition. We od this recursively

Can anyone suggest best possible way to drive this in such cases

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;
}
KBR
  • 464
  • 1
  • 7
  • 24

1 Answers1

0

To begin, look at your isPalindrome() method:

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;
}

This method looks at the first and last character in the string, and compares them. This has a time complexity of O(n/2), because it must loop through half of the length of the input to perform what it needs to do. This becomes O(n) asymptotically, because you ignore constant terms for Big-O notation.

Next, look at your decompose() method. These lines are the important ones for deriving time complexity:

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);
        }
}

Before we include the recursion, look at what the loop and the if-condition do. They loop through your input string character by character, and call the isPalendrome() function on each successive substring. Without the recursive call within the substring, this has time complexity O(n^2), as you are calling the isPalendrome() method (time complexity O(n)) n times. Thus, each non-recursive call of decompose() has time complexity O(n^2).

Adding in recursion, the worst case becomes pretty bad. If it calls itself every time, the complexity will be n*(n-1)*(n-2)*....., which simplified is O(n!). I derived the n*(n-1)*(n-2)*..... as the worst case by looking at what would happen if the if-condition were true every time. This means that for every iteration of the for loop, you would call the function, and each time on that call, you would call the function again each time, and that goes down and down until you hit the base case. This expressed mathematically is the sequence that simplifies to O(n!), which you then have to multiply by n^2. However, this simplifies to O(n!) asymptotically. The best case will be O(n^2), which is when there are no palindromes, and the average case will be closer to O(n^n), as you probably will be dealing with palindromes within words pretty often.

Lavaman65
  • 863
  • 1
  • 12
  • 22
  • Thanks @UnknowableIneffible for detailing out the explanation . However the way I was thinking in a simplified manner was , for any n characcter string , there would 2^n-1 partitions in total , while logic is looking at each partition to check if its palindrome , that makes time complexity to be O(n*2^n-1). isn't that right ? – KBR Mar 02 '17 at 20:22
  • Can you tell me how you got 2^n-1? Also, I just noticed that my math was wrong, it should be O(n!), not O(n^n). I fixed it. – Lavaman65 Mar 02 '17 at 21:26
  • lets say If I have String "abc" , between each character of a string , I can place a split. i.e.for n character string , I can have n-1 options to split.considering the fact I can either do split or not for each place , it takes to 2^n-1 . splits for abc are (a|b|c, a|bc,ab|c,abc) – KBR Mar 06 '17 at 02:44