[LeetCode] 132. 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.

Thought process:
  1. Sub-problem: find the minimum cuts needed for a palindrome partitioning of a substring of s.
  2. Function: f[i] = min(f[j]) + 1, where j < i and s[j, i] is a palindrome.
  3. Initialization: if there's only one character in the string, it requires no cut. So we set f[0] = -1 and f[1] will become 0. Further calculations where the whole string is a palindrome will also be easier.
  4. Answer: f[s.length].
How to check whether a substring is a palindrome?
The loop takes O(n^2) already. If we check if a string is a palindrome inside the loop, the overall time complexity will increase to O(n^3). To reduce the time complexity, we can check if every substring is a palindrome, and store the results before the dp. We use another dp to do this:
  1. Problem: if a substring of s is a palindrome.
  2. Function: g[i, j] = g[i + 1, j - 1] && g[i] == g[j].
  3. Initialization: every single character is a palindrome. g[i][0] = g[0][j] = true.
  4. Answer: the whole matrix.

Solution:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Solution {
    public int minCut(String s) {
        int length = s.length();
        if (length == 0) {
            return 0;
        }
        
        int[] f = new int[length + 1];
        f[0] = -1;
        
        boolean[][] isPalindrome = getPalindromes(s);
        
        for (int i = 1; i <= length; i++) {
            int min = Integer.MAX_VALUE;
            
            for (int j = 0; j < i; j++) {
                if (isPalindrome[j][i] && f[j] + 1 < min) {
                    f[i] = f[j] + 1;
                    min = f[i];
                }
            }
        }
        
        return f[length];
    }
    
    private boolean[][] getPalindromes(String s) {
        int length = s.length();
        boolean[][] isPalindrome = new boolean[length + 1][length + 1];
        
        for (int i = 0; i < length; i++) {
            isPalindrome[i][i] = true;
            isPalindrome[i][i + 1] = true;
        }
        
        for (int range = 2; range <= s.length(); range++) {
            for (int i = 0; i + range <= length; i++) {
                int right = i + range;
                isPalindrome[i][right] = isPalindrome[i + 1][right - 1] && s.charAt(i) == s.charAt(right - 1);
            }
        }
        
        return isPalindrome;
    }
}
Time complexity:
Both functions take O(n^2). The overall time complexity is O(n^2).

Comments

Popular posts from this blog

[LeetCode] 714. Best Time to Buy and Sell Stock with Transaction Fee

[LeetCode] 269. Alien Dictionary

[LeetCode] 631. Design Excel Sum Formula