Palindrome Partitioning II

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

Analysis

核心:

  • cut[i] 代表s的前i个字母至少需要cut多少次
  • scan s,从某一个位置i的左右开始去找。当找到一个palindrome的时候,更新cut的值为前面不是palindrome的部分cut值+1,因为前面的已经算好,加上一个palindrome,多cut一次即可
  • 最后返回cut[s.length]
Example: "aabbabc", return 3, aa | b | bab | c

        0   1   2   3   4   5   6   
        a   a   b   b   a   b   c
    -1  0   0   1   1   1   2   3

Initialize cut = [-1  0   1   2   3   4   5   6]

i=0: 
odd: "a" is palindrome, update cut[1] to min(0, -1+1)
even: "aa" is palindrome, update cut[2] to min(1, -1+1)
cut = [-1  0   0   2   3   4   5   6]

i=1:
odd: "a" is palindrome, update cut[2] to min(0, 0+1)
even: no palindrome
cut = [-1  0   0   2   3   4   5   6]

i=2:
odd: "b" is palindrome, update cut[3] to min(2, 0+1)
even: "bb" is palindrome, update cut[4] to min(3, 0+1)
      "abba" is palindrome, update cut[5] to min(4, 0+1)
cut = [-1  0   0   1   1   1   5   6]

i=3:
odd: "b" is palindrome, update cut[4] to min(1, 1+1)
even: no palindrome
cut = [-1  0   0   1   1   1   5   6]

i=4:
odd: "a" is palindrome, update cut[5] to min(1, 1+1)
even: "bab" is palindrome, update cut[6] to min(5, 1+1)
cut = [-1  0   0   1   1   1   2   6]

i=5:
odd: "b" is palindrome, update cut[6] to min(2, 1+1)
even: no palindrome
cut = [-1  0   0   1   1   1   2   6]

i=6:
odd: "c" is palindrome, update cut[7] to min(6, 2+1)
even: no palindrome
cut = [-1  0   0   1   1   1   2   3]

return cut[7]=3

Code

public class Solution {
    public int minCut(String s) {
        if (s==null || s.length()<=1) return 0;
        int len = s.length();

        //cut[i]: number of cuts for the first i chars
        int[] cut = new int[len+1];

        //initialize with maximum possible cuts (cut to single chars)
        for (int i=0; i<=len; i++) cut[i]=i-1;

        for (int i=0; i<len; i++){
            //odd length palindrome
            for (int j=0; i-j>=0 && i+j <len && s.charAt(i-j)==s.charAt(i+j); j++){
                cut[i+j+1] = Math.min(cut[i+j+1], 1+cut[i-j]);
            }
            //even length palindrome
            for (int j=1; i-j+1>=0 && i+j <len && s.charAt(i-j+1)==s.charAt(i+j); j++){
                cut[i+j+1] = Math.min(cut[i+j+1], 1+cut[i-j+1]);
            }
        }

        return cut[len];
    }
}

Reference

Leetcode