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

 

posted on 2016-10-23 01:47  kkkiii  阅读(163)  评论(0)    收藏  举报