“This is the 12th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
1049. The weight of the last stone II
Topic describes
We have a bunch of stones, represented by an array of integers called stones. Where stones[I] refers to the weight of the ith stone.
Each round, pick any two stones and smash them together. Suppose the stones weigh x and y, and x <= y. Then the possible results of shredding are as follows:
If x == y, then both stones will be completely shattered; If x! = y, then the stone weighing x will be completely crushed, and the stone weighing Y will have a new weight of Y-x. In the end, there will be no more than one stone left. Returns the minimum possible weight of this stone. If there are no stones left, 0 is returned.
Example 1:
Stones = [2,7,4,1,8,1] Combine 2 and 4 to get 2, so the array becomes [2,7,1,8,1], combine 7 and 8 to get 1, so the array becomes [2,1,1], combine 2 and 1 to get 1, so the array becomes [1,1,1], combine 1 and 1 to get 0, So the array is converted to [1], which is the optimal value.Copy the code
Example 2:
Stones = [31,26,33,21,40Copy the code
Example 3:
Stones = [1,2Copy the code
Method: Dynamic programming
Their thinking
The weight of the last stone, M, can be expressed as sum-neg-neg, where sum is the sum of all integers and neg is the sum of all integers added -, then neg = (sum-m) / 2
To make M as small as possible, neg as large as possible, Max. Math.floor(sum / 2)
Define a two-dimensional Boolean array dp, dp[I][j] indicates whether: select several elements from the first I number of array, and is j
-
Dp [0][0] = true, dp[0][j] = false (j! = 0)
-
i ! = 0 for the ith element num
If j < num, then dp[I][j] = dp[i-1][j], that is, it is impossible to choose this element, whether the sum of the former i-1 number can be j depends on whether the sum of the former i-1 number can be j
If j > = num, dp [I] [j] = dp [j] [I – 1] | | dp [I – 1] [j – num], namely the number before I can do it and for j is divided into two cases
- before
i-1
The number can add up to zeroj
Before,i
The number can be in noi
The sum of the numbers is j - before
i-1
The number can add up to zeroj-num
Before,i
And the number can be pickedi
When the sum is j
- before
To optimize the
Since each row of DP is evaluated only with respect to the previous row, instead of using a two-dimensional array, you can use a scrolling array to remove the first dimension of DP
The memory loop should be traversed backwards from the maximum value of j, ensuring that the elements of dp[i-1][] are transferred
code
/ * * *@param {number[]} stones
* @return {number}* /
var lastStoneWeightII = function(stones) {
const n = stones.length
let sum = 0
stones.forEach(item= > {
sum += item
})
const neg = Math.floor(sum / 2)
const dp = new Array(neg + 1).fill(false)
dp[0] = true
for (let stone of stones) {
for (let j = neg; j >= stone; j--) {
dp[j] = dp[j] || dp[j - stone]
}
}
for (let i = neg; i >= 0; i--) {
if (dp[i]) {
return sum - 2 * i
}
}
};
Copy the code
Algorithm complexity analysis
- Time complexity: O(n * sum)
- Space complexity: O(sum)