Welcome to Subscribe On Youtube
1049. Last Stone Weight II
Description
You are given an array of integers stones where stones[i] is the weight of the ith stone.
We are playing a game with the stones. On each turn, we choose any two stones and smash them together. Suppose the stones have weights x and y with x <= y. The result of this smash is:
- If
x == y, both stones are destroyed, and - If
x != y, the stone of weightxis destroyed, and the stone of weightyhas new weighty - x.
At the end of the game, there is at most one stone left.
Return the smallest possible weight of the left stone. If there are no stones left, return 0.
Example 1:
Input: stones = [2,7,4,1,8,1] Output: 1 Explanation: We can combine 2 and 4 to get 2, so the array converts to [2,7,1,8,1] then, we can combine 7 and 8 to get 1, so the array converts to [2,1,1,1] then, we can combine 2 and 1 to get 1, so the array converts to [1,1,1] then, we can combine 1 and 1 to get 0, so the array converts to [1], then that's the optimal value.
Example 2:
Input: stones = [31,26,33,21,40] Output: 5
Constraints:
1 <= stones.length <= 301 <= stones[i] <= 100
Solutions
Solution 1
Dynamic programming.
This question can be converted to calculate how many stones a knapsack with a capacity of sum / 2 can hold.
Solution 2
This implementation uses dynamic programming, followed by bit manipulation. It traverses the relevant values and updates its state as each value is processed. Previously computed states are retained so the same subproblem does not need to be solved again. After all required states have been considered, the maintained result is returned.
-
class Solution { public int lastStoneWeightII(int[] stones) { int s = 0; for (int v : stones) { s += v; } int m = stones.length; int n = s >> 1; int[] dp = new int[n + 1]; for (int v : stones) { for (int j = n; j >= v; --j) { dp[j] = Math.max(dp[j], dp[j - v] + v); } } return s - dp[n] * 2; } } // Solution 2 class Solution { public int lastStoneWeightII(int[] stones) { int s = 0; for (int v : stones) { s += v; } int m = stones.length; int n = s >> 1; int[] dp = new int[n + 1]; for (int v : stones) { for (int j = n; j >= v; --j) { dp[j] = Math.max(dp[j], dp[j - v] + v); } } return s - dp[n] * 2; } } -
class Solution { public: int lastStoneWeightII(vector<int>& stones) { int s = accumulate(stones.begin(), stones.end(), 0); int n = s >> 1; vector<int> dp(n + 1); for (int& v : stones) for (int j = n; j >= v; --j) dp[j] = max(dp[j], dp[j - v] + v); return s - dp[n] * 2; } }; // Solution 2 class Solution { public: int lastStoneWeightII(vector<int>& stones) { int s = accumulate(stones.begin(), stones.end(), 0); int n = s >> 1; vector<int> dp(n + 1); for (int& v : stones) for (int j = n; j >= v; --j) dp[j] = max(dp[j], dp[j - v] + v); return s - dp[n] * 2; } }; -
class Solution: def lastStoneWeightII(self, stones: List[int]) -> int: s = sum(stones) m, n = len(stones), s >> 1 dp = [0] * (n + 1) for v in stones: for j in range(n, v - 1, -1): dp[j] = max(dp[j], dp[j - v] + v) return s - dp[-1] * 2 # Solution 2 class Solution: def lastStoneWeightII(self, stones: List[int]) -> int: s = sum(stones) m, n = len(stones), s >> 1 dp = [0] * (n + 1) for v in stones: for j in range(n, v - 1, -1): dp[j] = max(dp[j], dp[j - v] + v) return s - dp[-1] * 2 -
func lastStoneWeightII(stones []int) int { s := 0 for _, v := range stones { s += v } n := s >> 1 dp := make([]int, n+1) for _, v := range stones { for j := n; j >= v; j-- { dp[j] = max(dp[j], dp[j-v]+v) } } return s - dp[n]*2 } // Solution 2 func lastStoneWeightII(stones []int) int { s := 0 for _, v := range stones { s += v } n := s >> 1 dp := make([]int, n+1) for _, v := range stones { for j := n; j >= v; j-- { dp[j] = max(dp[j], dp[j-v]+v) } } return s - dp[n]*2 } -
/** * @param {number[]} stones * @return {number} */ var lastStoneWeightII = function (stones) { let s = 0; for (let v of stones) { s += v; } const n = s >> 1; let dp = new Array(n + 1).fill(0); for (let v of stones) { for (let j = n; j >= v; --j) { dp[j] = Math.max(dp[j], dp[j - v] + v); } } return s - dp[n] * 2; }; -
impl Solution { #[allow(dead_code)] pub fn last_stone_weight_ii(stones: Vec<i32>) -> i32 { let n = stones.len(); let mut sum = 0; for e in &stones { sum += *e; } let m = (sum / 2) as usize; let mut dp: Vec<Vec<i32>> = vec![vec![0; m + 1]; n + 1]; // Begin the actual dp process for i in 1..=n { for j in 1..=m { dp[i][j] = if stones[i - 1] > (j as i32) { dp[i - 1][j] } else { std::cmp::max( dp[i - 1][j], dp[i - 1][j - (stones[i - 1] as usize)] + stones[i - 1] ) }; } } sum - 2 * dp[n][m] } }