Leetcode-DP

70

class Solution {
    public int climbStairs(int n) {
               if (n<1){
            return 0;
        }
        else if(n==1)
            return 1;
        else if(n==2)
            return 2;
        else{
            int ans = 0;
            int a = 1, b=2;
            for (int i=3; i<=n; i++){
                ans = a + b;
                a = b;
                b = ans;
            }
            return ans;
        }
    }
}

91

https://www.tianmaying.com/tutorial/LC91

class Solution {
    public int numDecodings(String s) {
        if (s.length()==0)
            return 0;
        int[] dp = new int[s.length()+1];
        dp[0] = 1;
        for (int i=1; i<=s.length(); i++){
            if (s.charAt(i-1) >'0' ){
                dp[i] += dp[i-1];
            }
            if(i>1 && (s.substring(i-2, i).compareTo("09")>0)  && ("27".compareTo(s.substring(i-2, i))>0)){
                dp[i] += dp[i-2];
            }
        }
        return dp[s.length()];
    }
}

95

很奇怪,n=0处理

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<TreeNode> generate(int start, int end){
        List<TreeNode> treeList = new ArrayList<TreeNode>();
        if(start>end){
            treeList.add(null);
            return treeList;
        }
        for (int i=start; i<=end; i++){

            List<TreeNode> leftList = generate(start, i-1);
            List<TreeNode> rightList = generate(i+1, end);
            for (int j=0; j<leftList.size(); j++){
                for (int k=0; k<rightList.size(); k++){
                    TreeNode root = new TreeNode(i);
                    root.left = leftList.get(j);
                    root.right = rightList.get(k);
                    treeList.add(root);
                }
            }
        }
        return treeList;
    }
    public List<TreeNode> generateTrees(int n) {
        if (n==0)
            return new ArrayList<TreeNode>();
        return generate(1, n);
    }
}

96

1-dp

左右子树递归调用原来的dp值。

f(0) = 1

f(n) = f(0)*f(n-1) + f(1)f(n-2) + ... + f(n-2)f(1) + f(n-1)*f(0)

class Solution {
    public int numTrees(int n) {
        if(n==0)
            return 0;
        if(n==1)
            return 1;
        int[] dp = new int[n+1];
        dp[0]=1;
        dp[1]=1;
        for (int i=2; i<=n; i++){
           for (int j=0; j<i; j++){
               dp[i] += dp[j]*dp[i-1-j];
           }
        }
        return dp[n];
    }
}

139

http://www.jianshu.com/p/bb07e7825212

import javax.swing.tree.TreeNode;
import java.util.List;

class Solution {
    public boolean isContain(List<String> wordDict, String s){
        for (String word : wordDict){
            if(word.equals(s))
                return true;
        }
        return false;
    }
    public boolean wordBreak(String s, List<String> wordDict) {
        int length = s.length();
        if (length==0)
            return false;
        boolean[] dp = new boolean[length+1];
        dp[0] = true;
        for (int i=1; i<=length; i++){
            for (int j=i-1; j>=0; j--){
                if (dp[j] && isContain(wordDict, s.substring(j, i))){
                    dp[i]=true;
                    break;
                }
            }
        }
        return dp[length];
    }
}

198

class Solution {
    public int rob(int[] nums) {
        int a=0, b=0, c=0; //dpi, dpi-1, dpi-2
        if(nums.length<1)
            return 0;
        else if(nums.length==1)
            return nums[1];
        else if(nums.length==2){
            int ans = nums[1]>nums[0]? nums[1]: nums[0];
            return ans;
        }
        c = nums[0];
        b = nums[1]>nums[0] ? nums[1]: nums[0];
        a = (nums[1]>nums[0]+nums[2])?nums[1]:nums[0]+nums[2];
        for(int i=2;i<nums.length; i++){
            int val1 = c+nums[i];
            int val2 = b;
            if (val1>val2){
                a= val1;
            }
            else
                a= val2;
            c = b;
            b = a;
        }
        return a;
    }
}

213

参考198

是House Robber的扩展题(http://fisherlei.blogspot.com/2017/07/leetcode-house-robber-solution.html ),唯一的区别就是house 0 和house n-1相邻了。根据题目要求,不能抢劫相邻的房子,所以这个环把它拆开就两种可能:

  1. 抢劫house 0,那么就不能抢劫house n-1,所以抢劫的范围就是[0, n-2]
  2. 不抢劫house 0,那么就得从house 1开始抢,抢劫的范围就是[1, n-1]

对于#1和#2两种情况,都可以复用House Robber的代码, 最后比较一下这两种可能中,那个收入多即可。

class Solution {
    public int maxVal(int a, int b){
        return a>b?a:b;
    }
    public int rob(int[] nums) {
        int size = nums.length;
        if (size<1)
            return 0;
        if (size==1)
            return nums[0];
        else if (size==2)
            return maxVal(nums[0],nums[1]);

        int a=nums[0], b=maxVal(nums[0],nums[1]);
        int res1 = maxVal(a,b);
        for(int i=2; i<size-1; i++){
            res1 = maxVal(a+nums[i], b);
            a = b;
            b = res1;
        }
        a = nums[1];
        b=maxVal(nums[1], nums[2]);
        int res2 = maxVal(a, b);
        for(int i=3; i<size; i++){
            res2 = maxVal(a+nums[i], b);
            a = b;
            b = res2;
        }
        return maxVal(res1, res2);
    }

}

221

根据经验,一眼便看出这是一道 动态规划 题。我们用 dp[i][j] 表示以 matrix[i][j] 为右下角的最大全 1 正方形的边长,仔细思考,如何推得 dp[i][j] 的递推公式?

dp[i][j] 可以从三部分推得,首先是 dp[i-1][j-1],然后是 matrix[i][j] 左边的连续 1 的个数,然后是 matrix[i][j] 上面连续 1 的个数,这三部分取最小值。于是我们可以维护三个数组,dp[i][j] 表示以 matrix[i][j] 为右下角的全 1 正方形的边长,a[i][j] 表示从 matrix[i][j] 往左的连续 1 的个数,b[i][j] 表示从 matrix[i][j] 往上的连续 1 的个数。

class Solution {
    public int min3(int a, int b, int c){
        if(a>b)
            a=b;
        if(a>c)
            a=c;
        return a;
    }
    public int maximalSquare(char[][] matrix) {
        if(matrix.length==0 || matrix[0].length==0)
            return 0;
        int m = matrix.length;
        int n = matrix[0].length;
        int maxLength = 0;
        int[][] dp = new int[m+1][n+1];
        for(int i=1; i<=m; i++){
            for(int j=1; j<=n; j++){
                if(matrix[i-1][j-1]=='1')
                    dp[i][j] = min3(dp[i-1][j-1], dp[i-1][j], dp[i][j-1])+1;
                maxLength = dp[i][j] > maxLength? dp[i][j] : maxLength;
            }
        }
        return maxLength*maxLength;
    }
}

264

Dp

https://discuss.leetcode.com/topic/21882/my-16ms-c-dp-solution-with-short-explanation

class Solution {
    public int nthUglyNumber(int n) {
        int[] dp = new int[n+1];
        dp[0] = 1;
        int i1=0;
        int i2=0;
        int i3=0;
        for(int i=1; i<n; i++){
            dp[i] = Math.min(Math.min(dp[i1]*2, dp[i2]*3), dp[i3]*5);
            if(dp[i]==dp[i1]*2)
                i1++;
            if(dp[i]==dp[i2]*3)
                i2++;
            if(dp[i]==dp[i3]*5)
                i3++;
        }
        return dp[n-1];
    }
}

303

1-DP

边界条件可以写的更精致一些

class NumArray {
    int[] sumI;
    int[] nums;
    public NumArray(int[] nums) {
        this.nums = nums;
        sumI = new int[nums.length];
        int sum = 0;
        for(int i=0; i<nums.length; i++){
            sum += nums[i];
            sumI[i] = sum;
        }
    }

    public int sumRange(int i, int j) {
        return sumI[j] - sumI[i] + nums[i];
    }
}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(i,j);
 */

416

1-dp-01pack

Ref-494

https://discuss.leetcode.com/topic/67539/0-1-knapsack-detailed-explanation/2

class Solution {
    public  boolean canPartition(int[] nums) {
        int sum = 0;
        for (int n : nums){
            sum+=n;
        }
        if (sum%2==1)
            return false;
        System.out.println(sum);
        sum /= 2;
        boolean[] dp = new boolean[sum+1];

        dp[0] = true;

        for (int n : nums){
            for (int v=sum; v>=n; v--){
                dp[v] = dp[v] || dp[v-n];
            }
        }
        if (dp[sum])
            return true;
        else
            return false;

    }
}

494

class Solution {
    int cnt = 0;
    public int findTargetSumWays(int[] nums, int S) {
        if (nums.length<1)
            return 0;
        helper(nums, S, 0);
        return cnt;
    }
    public void helper(int[] nums, int currentS, int index){
        if (index >= nums.length){
            if (currentS==0)
                cnt++;
            return;
        }
        helper(nums, currentS+nums[index], index+1);
        helper(nums, currentS-nums[index], index+1);
    }
}

2-增加记录

class Solution {
    public int findTargetSumWays(int[] nums, int S) {
        if (nums.length<1)
            return 0;
        Map<String, Integer> cntMap = new HashMap<>();
        return helper(nums, S, 0, cntMap);
    }
    public int helper(int[] nums, int currentS, int index, Map<String, Integer> cntMap){
        String key = index+"-"+currentS;
        if (cntMap.containsKey(key))
            return cntMap.get(key);
        if (index == nums.length){
            if (currentS==0)
                return 1;
            return 0;
        }
        int cntPlus = helper(nums, currentS+nums[index], index+1, cntMap);
        int cnrMinus = helper(nums, currentS-nums[index], index+1, cntMap);
        cntMap.put(key, cnrMinus+cntPlus);
        return cnrMinus+cntPlus;
    }
}

3-

0-1背包问题

https://discuss.leetcode.com/topic/76243/java-15-ms-c-3-ms-o-ns-iterative-dp-solution-using-subset-sum-with-explanation

class Solution {
    public int findTargetSumWays(int[] nums, int S) {
        int sum = 0;
        for (int num : nums){
            sum += num;
        }
        if (sum<S || (sum+S)%2==1)
            return 0;
        int newSum = (sum+S)/2;
        int[] dp =  new int[newSum+1];
        dp[0] = 1;
        for (int n : nums){
            for(int v=newSum; v>=n; v--){
                dp[v] += dp[v-n];
            }
        }
        return dp[newSum];
    }

}

650

1-Iteration

https://discuss.leetcode.com/topic/97752/very-simple-java-solution-with-detail-explanation/2

https://discuss.leetcode.com/topic/97623/loop-best-case-log-n-no-dp-no-extra-space-no-recursion-with-explanation/2

class Solution {
    public int minSteps(int n) {
        int ans = 0;
        for(int i=2; i<=n; i++){
            while (n%i==0){
                ans += i;
                n /= i;
            }
        }
        return ans;
    }
}

2-Dp

思路形同

class Solution {
    public int minSteps(int n) {
        int[] dp = new int[n+1];
        for (int i=2; i<=n; i++){
            dp[i] = i;
            for (int j=i-1; j>1; j--){
                if(i%j==0){
                    dp[i] = Math.min(dp[i], dp[j]+i/j);
                }
            }
        }
        return dp[n];
    }
}

results matching ""

    No results matching ""