[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 =
Return
"aab"
,Return
1
since the palindrome partitioning ["aa","b"]
could be produced using 1 cut.
Thought process:
- Sub-problem: find the minimum cuts needed for a palindrome partitioning of a substring of s.
- Function: f[i] = min(f[j]) + 1, where j < i and s[j, i] is a palindrome.
- 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.
- 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:
- Problem: if a substring of s is a palindrome.
- Function: g[i, j] = g[i + 1, j - 1] && g[i] == g[j].
- Initialization: every single character is a palindrome. g[i][0] = g[0][j] = true.
- 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
Post a Comment