最后一块石头的重量 II
难度:
标签:
题目描述
代码结果
运行时间: 21 ms, 内存: 16.0 MB
/*
* 思路:
* 1. 将所有石头总重量的一半作为背包容量。
* 2. 使用动态规划找到最接近这个容量的组合。
* 3. 最小可能重量是总重量减去两倍的最大可达背包重量。
*/
import java.util.Arrays;
public class Solution {
public int lastStoneWeightII(int[] stones) {
int sum = Arrays.stream(stones).sum();
int target = sum / 2;
int[] dp = new int[target + 1];
Arrays.stream(stones).forEach(stone -> {
for (int j = target; j >= stone; j--) {
dp[j] = Math.max(dp[j], dp[j - stone] + stone);
}
});
return sum - 2 * dp[target];
}
}
解释
方法:
此题可以转化为一个经典的动态规划问题。我们可以将问题理解为如何将石头分为两堆,使得这两堆石头的重量之差最小。这是一个类似于背包问题的变种,其中我们尝试找到总重量不超过总重量一半的最大重量。我们使用一个位向量来表示可以达到的重量,初始时只有重量0是可达的。对于每块石头,我们更新这个位向量,标记新的可达重量。最后,我们从最大可达重量开始向下检查,找到最接近总重量一半的值,这样可以保证两堆石头的重量差最小。
时间复杂度:
O(n * total/2)
空间复杂度:
O(total/2)
代码细节讲解
🦆
题解中提到'将问题转化为动态规划问题',请问是如何从原问题描述到动态规划这一转变的?具体是哪些逻辑使得这个问题可以看作是背包问题的变形?
▷🦆
在动态规划解法中,位向量的更新操作`v |= v >> s`是如何工作的?能否详细解释这个操作如何帮助追踪可达的重量?
▷🦆
题解提到使用位向量来存储状态,这种方法与常规的动态规划数组有何不同?使用位向量有什么特别的优势吗?
▷