算法训练营第四十五天 | LeetCode 1049 最后一块石头的重量II、LeetCode 494 目标和、LeetCode 474 一和零

LeetCode 1049 最后一块石头的重量


  1. 继续昨天没有详细说的01背包问题往下继续说。01背包问题是将dp从一维问题升维到二维 之后会遇到的一类典型问题 。dp数组自然而然地是一个横坐标表示物品序号-1,纵坐标表示背包重量的二维数组
  2. 01背包由一个背包是否放该物品并比照后得到最大值 ,来表示表示子问题和当前问题之间关系组成递推逻辑。 递推过程中由于物品数组逐渐增加,dpij在每一轮总是由dpi-1j递推而来,因此可以简化为用一维滚动数组来表示 。但这样第二重循环中由于从前往后遍历dpi0会被存放多次,因此要从后往前遍历,同时由于我们递推公式是一个将i号物品放入背包,j减去其容量值将dp数组值加上物品value的过程,这个过程逆序时前面的dp值也是正常放入了值不会被覆盖的。也因此,我们可以采用一维数组来节省空间,但要稍微调整内层循环遍历顺序。

初始化都默认为零即可。

java 复制代码
class Solution {
    public int lastStoneWeightII(int[] stones) {
        int sum = 0;
        for (int i = 0; i < stones.length; i++) {
            sum += stones[i];
        }
        int weight = sum / 2;
        int[] dp = new int[weight + 1];
        for (int i = 0; i < stones.length; i++) {
            for (int j = weight; j >= stones[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        return (sum - dp[weight] * 2);
    }
}

这道题转化为01背包问题的思路可以自行思考或者参照题解。

LeetCode 494 目标和


  • 这一题其实还是可以转化为01背包问题。不过要加上目标数之后除以2,如果加上之后为奇数或者小于0就直接返回0即可。否则我们直接用01背包模式求解即可。但是要注意由于我们求的是方法数,所以要更改下递推公式为加上之前子问题的方法数。

代码如下:

java 复制代码
class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        sum += target;
        if (sum < 0) return 0;
        if (sum % 2 == 1) return 0;
        sum /= 2;
        int[] dp = new int[sum + 1];
        dp[0] = 1;
        for (int i = 0; i < nums.length; i++) {
            for (int j = sum; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[sum];
    }
}

LeetCode 474 一和零


这题和上面差不多,还是用的01背包问题,而且要更明显一些。

代码如下:

java 复制代码
class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        int[] n0 = new int[strs.length];
        int[] n1 = new int[strs.length];
        for (int i = 0; i < strs.length; i++) {
            for (int j = 0; j < strs[i].length(); j++) {
                if (strs[i].charAt(j) == '0') n0[i]++;
                else n1[i]++;
            }
        }
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 0; i < strs.length; i++) {
            for (int j = m; j >= n0[i]; j--) {
                for (int k = n; k >= n1[i]; k--) {
                    dp[j][k] = Math.max(dp[j][k], dp[j - n0[i]][k - n1[i]] + 1);
                }
            }
        }
        return dp[m][n];
    }
}
相关推荐
碳基猿31 分钟前
案例|普通内容创作者如何利用 CreBee 打造个人内容创业系统:从一个账号到多平台内容资产矩阵
职场和发展·新媒体运营·创业创新·程序员创富·新媒体矩阵
203号居民2 小时前
LeetCode hot 100 —41. 缺失的第一个正数
数据结构·算法·leetcode
专注仿真4 小时前
问答大模型技术方案算法实现-熵权法融合算法 + 交叉编码器重排算法
人工智能·python·算法·语言模型·问答大模型关键算法·熵权融合算法·交叉编码器重排算法
地平线开发者5 小时前
量化为什么会有损失:从量化误差到精度下降
算法
手写码匠5 小时前
华为云Flexus+DeepSeek征文|Dify 多 Agent 会话管理与上下文工程实战:让智能体“记住该记住的,忘掉该忘掉的“
人工智能·深度学习·算法·aigc
2401_862880825 小时前
数据结构 --- 栈
c语言·数据结构·算法
致Great6 小时前
Qwen3.8-27B 接入 DSH 全流程实测:写代码、跑长任务,都没问题
算法
Tisfy6 小时前
LeetCode 3471.找出最大的几近缺失整数:三种情况判断
算法·leetcode·题解·分类讨论
linux-hzh7 小时前
百日算法修炼 · Day 12
算法·深度优先
额额额对了7 小时前
数据结构:二叉树
c语言·数据结构·算法