class Solution:
def lastStoneWeightII(self, stones):
total = sum(stones)
target = total // 2
dp = [False] * (target + 1)
dp[0] = True
for stone in stones:
for i in range(target, stone - 1, -1):
dp[i] = dp[i] or dp[i - stone]
for i in range(target, -1, -1):
if dp[i]:
return total - 2 * i
class Solution {
public:
int lastStoneWeightII(vector<int>& stones) {
int total = accumulate(stones.begin(), stones.end(), 0);
int target = total / 2;
vector<bool> dp(target + 1, false);
dp[0] = true;
for (int stone : stones) {
for (int i = target; i >= stone; --i) {
dp[i] = dp[i] || dp[i - stone];
}
}
for (int i = target; i >= 0; --i) {
if (dp[i]) return total - 2 * i;
}
return 0;
}
};
class Solution {
public int lastStoneWeightII(int[] stones) {
int total = 0;
for (int s : stones) total += s;
int target = total / 2;
boolean[] dp = new boolean[target + 1];
dp[0] = true;
for (int stone : stones) {
for (int i = target; i >= stone; --i) {
dp[i] = dp[i] || dp[i - stone];
}
}
for (int i = target; i >= 0; --i) {
if (dp[i]) return total - 2 * i;
}
return 0;
}
}
var lastStoneWeightII = function(stones) {
let total = stones.reduce((a, b) => a + b, 0);
let target = Math.floor(total / 2);
let dp = new Array(target + 1).fill(false);
dp[0] = true;
for (let stone of stones) {
for (let i = target; i >= stone; --i) {
dp[i] = dp[i] || dp[i - stone];
}
}
for (let i = target; i >= 0; --i) {
if (dp[i]) return total - 2 * i;
}
return 0;
};
stones
where each element represents the weight of a stone. In each turn, you can choose any two stones and smash them together. If the stones have equal weight, both are destroyed. If they have different weights, the stone with the larger weight is replaced by the difference, and the smaller one is destroyed. This process repeats until there is at most one stone left. Your task is to return the smallest possible weight of the remaining stone (or 0 if all stones are destroyed).total
be the sum of all stones.sum1
, and the other sum2 = total - sum1
.abs(sum1 - sum2) = abs(total - 2 * sum1)
.sum1
less than or equal to total // 2
that can be formed by selecting a subset of stones.dp
of size target + 1
(where target = total // 2
), where dp[i]
is true if a subset sum of i
can be formed.dp
array from high to low to avoid using the same stone multiple times.i
where dp[i]
is true and return total - 2 * i
as the answer.stones = [2,7,4,1,8,1]
.23 - 2*11 = 1
.n
stones is 2^n
, so time complexity is exponential and infeasible for large n
.n
stones and total sum S
, time complexity is O(n * S/2)
since for each stone, we process up to S/2
subset sums. Space complexity is O(S/2)
for the DP array.