LeetCode:1049. 最后一块石头的重量 II - 力扣(LeetCode)
1.思路
尝试将物品拆分成尽可能相近的两部分,两者相减才能得出剩余的最小值。具体操作:求和/2得出背包容量值,背包容量下所能盛放的最大重量由不放当前石头和放当前石头决定。最终结果是总和减去两倍(选出与被撞)的当前容量的值。
2.代码实现
class Solution {
public int lastStoneWeightII(int[] stones) {
int sum = 0;
for (int i : stones) {
sum += i;
}
// int target = sum >> 1;
int target = sum / 2;
// 初始化dp[]数组:dp[target]表示容量在target时所能盛放的最大值
int[] dp = new int[target + 1];
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]);
}
}
return sum - 2 * dp[target];
}
}
3.复杂度分析
时间复杂度:O(N * M).
空间复杂度:O(N).
LeetCode:494. 目标和 - 力扣(LeetCode)
1.思路
为所有数字添加+-号得出target,则需要判断两块数字的和为sum下两块数字的值分别为size和right(size + right = sum; size - right = target),对物品进行遍历判断和为size存在的个数即可。
2.代码实现
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 > 0 && target > sum) {
return 0;
}
if (target < 0 && sum < -target) {
return 0;
}
// 设目标为target时,正数为left,负数为right。left + right = sum; left - right = target;
// size 为正数的值
int size = (sum + target) / 2;
if (size < 0) {
size = - size;
}
int[] dp = new int[size + 1];
dp[0] = 1;
for (int i = 0; i < nums.length; i++) {
for (int j = size; j >= nums[i]; j--) {
dp[j] += dp[j - nums[i]];
}
}
return dp[size];
}
}
3.复杂度分析
时间复杂度:O(N * M).
空间复杂度:O(N).
LeetCode:
1.思路
判断条件从一个变为两个,则dp[][]声明为二维的,对相应的0和1共同进行判断。遍历每个字符串,对字符串内元素个数进行判断,再将其放入背包,取其最大值即可。
2.代码实现
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
// 创建dp[i][j]:表示 i 个0和 j 个1时的最大子集数
int[][] dp = new int[m + 1][n + 1];
// 初始化均为 0 即可,也即默认即可
for (int i = 0; i < strs.length; i++) { // 物品
// 当前字符串中所具有的 0 和 1 的个数
int oneNum = 0;
int zeroNum = 0;
char[] ch = strs[i].toCharArray();
for (int j = 0; j < ch.length; j++) {
if (ch[j] == '0') {
zeroNum++;
} else {
oneNum++;
}
}
// 背包倒序遍历,避免重复内容加入
for (int k = m; k >= zeroNum; k--) {
for (int l = n; l >= oneNum; l--) {
dp[k][l] = Math.max(dp[k][l], dp[k - zeroNum][l - oneNum] + 1);
}
}
}
return dp[m][n];
}
}
3.复杂度分析
时间复杂度:O(N * m * n).
空间复杂度:O(N).