动态规划
01背包问题
思路:
先找出所有石头重量的总和,之后需要找的 target
就是 sum / 2
因为把石头分成两堆近似重量的时候对撞可以保证最后剩余的重量最小
关键是递推方程 (01 背包问题)
dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]
dp[j]
的定义是: 容量为 j
的背包装的最大重量(target
)的石头
遍历每个石头,再遍历容量 j
,找到包含当前石头 i
的最大容量 dp[j]
之后 dp[target]
即为 容量为 target
的时候最多能装多少重量的石头
因此, sum - dp[target]
就是最终剩余的最小的石头重量
class Solution {
public int lastStoneWeightII(int[] stones) {
int sum = 0;
for (int i : stones) {
sum += i;
}
int target = sum >> 1;
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 - dp[target] * 2;
}
}
时间: O(m * n)
. n
为 石头块数, m
为石头总重量
空间: O(m)