随想录训练营Day43 | DP - - 1049.最后一块石头的重量II, 494. 目标和, 474. 1 & 0

55 阅读1分钟

随想录训练营Day43 | DP - - 1049.最后一块石头的重量II, 494. 目标和, 474. 1 & 0

标签: LeetCode闯关记


1049.最后一块石头的重量II

key: 把这堆石头,尽可能分成重要相等的两堆,cf:416. 分割等和子集

class Solution {
    public int lastStoneWeightII(int[] stones) {
        int[] dp = new int[1501];
        int sum = 0;
        for (int i = 0; i < stones.length; i++) {
            sum += stones[i];
        }
        int target = sum/2;
        for (int i = 0; i < stones.length; i++) {
            for (int j = target; j >= stones[i] ; j--) {
                dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        int result = sum - dp[target] - dp[target];
        return result;
    }
}

494. 目标和

思路 img_41_1.png

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;

        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        if(target > sum || target < -sum){//target过大和过小的特殊情况
            return 0;
        }

        if((target + sum) % 2 != 0 ){
            return 0;
        }
        int positive = (target + sum)/ 2;
        if(positive < 0){
            positive = -positive;
        }
        int[] dp = new int[positive + 1];
        for (int i : dp) {
            i = 0;
        }
        dp[0] = 1;
        for (int i = 0; i < nums.length; i++) {
            for (int j = positive; j > nums[i] - 1 ; j--) {
                dp[j] = dp[j] + dp[j - nums[i]];
            }
        }
        return dp[positive];
    }
}

time:1h14min

474. 1 & 0

思路 img_41_2.png

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        int[][] dp = new int[m+1][n+1];
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n ; j++) {
                dp[i][j] = 0;
            }
        }
        for (int i = 0; i < strs.length; i++) {
            int x = 0;//统计有x个0
            int y = 0;//统计有y个1
            for (int j = 0; j < strs[i].length(); j++) {
                if(strs[i].charAt(j) == '0'){
                    x++;
                }else {
                    y++;
                }
            }
            for (int k1 = m; k1 >= x; k1--) {
                for (int k2 = n; k2 >= y; k2--) {
                    dp[k1][k2] = Math.max(dp[k1-x][k2-y]+1,dp[k1][k2]);
                    if(x==4 && y==2 ){
                        System.out.println("x="+ x +" y=" + y + "left=" + dp[k1-x][k2-y]+1 + "right=" + dp[k1][k2]);
                    }
                    System.out.println("k1=" + k1 + " k2=" + k2 + " dp[k1][k2]=" + dp[k1][k2]);
                }
            }
        }
        return dp[m][n];
    }

time: 1h30min