One sequence DP problems
1. Climbing stairs
easiest one shot
[TO DO]
2. Jump game
[TO DO]
3. Jump game II
[TO DO]
4. Palindrome Partitioning II (https://leetcode.com/problems/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.
Solution:
What is a palindrome? "a" "aa" "aba"
We should better use DP twice to solve this problem, one for determining whether current string is a palindrom, the other one for partitioning.
Palindrome DP:
status: f(i,j) whether the substring from index i to index j is a palindrome
function: f(i,j) = {s(i) == s(j) && [ f(i+1,j-1) || i - j <=1]}
start: f(i,i) = true, as any single character is a palindrome.
answer: we will use the result later in the next DP
Partition DP:
status: f(i) minimum cut for the first i character
function: f(i) = Min (f(j) + 1 , j < i && (j+1, i) is palindrome)
start: f(i) = i-1, f(1) = 0 => f(0) = -1,
answer: f(s.length)
public class Solution { public int minCut(String s) { int length = s.length(); if(s == null || length == 0) return 0; boolean[][] dict = getDict(s); int[] res = new int[length+1]; res[0] = -1; // res[1] = 0, only one character, res[0] = 0 - 1 = -1 for (int i = 0; i < length; i++) { res[i+1] = i; for(int j= 0; j <= i; j++) { if(dict[j][i]) res[i+1] = Math.min(res[i+1], res[j] + 1); } } return res[length] ; } public boolean[][] getDict(String s) { int length = s.length(); boolean[][] dict = new boolean[length][length]; for(int i = 0; i < length; i++) { // each single character is palindrome dict[i][i] = true; for(int j = 0; j < i; j++) { if(s.charAt(i) == s.charAt(j) && (i - j <= 1 || dict[j+1][i-1])) dict[j][i] = true; } } return dict; } }
5. Word break (https://leetcode.com/problems/word-break/)
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode",
dict = ["leet", "code"].
Return true because "leetcode" can be segmented as "leet code".
Solution:
status: f(i): whether the first i char can be break
function: f(i) = Or {f(j), j < i && (j+1, i) is a word in dic} // point find word
initialization f(0) = true
answer: f[s.length]]
public class Solution { public boolean wordBreak(String s, Set<String> wordDict) { if (s == null || s.length() == 0) return false; int length = s.length(); boolean[] dp = new boolean[length+1]; dp[0] = true; for (int i = 0; i < length; i++) { for (int j= 0; j <= i; j++) { if (dp[j] && wordDict.contains(s.substring(j, i+1))) { dp[i+1] = true; break; } } } return dp[length]; } }
6. Longest increasing substring (https://leetcode.com/problems/longest-increasing-subsequence/)
Solution:
state:
wrong: f[i] LIS within the first i elements
correct: f[i] LIS ending with i
function: f(i) = Max(f(j) + 1, j < i && a[j] < = a[i])
start: f[0.. n-1] = 1 // each single number is a increasing substring
answer: max (f[0.. n-1]])
public class Solution { public int lengthOfLIS(int[] nums) { if (nums == null || nums.length == 0) return 0; int[] dp = new int[nums.length]; Arrays.fill(dp, 1); for (int i = 0; i < nums.length; i++) { for (int j =0; j < i; j++) { if ( nums[i] > nums[j] ) { dp[i] = Math.max(dp[i],dp[j]+1); } } } int res = 0; for (int i : dp) { res = Math.max(res, i); } return res; } }
浙公网安备 33010602011771号