Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/740.html
740. Delete and Earn (Medium)
Given an array nums
of integers, you can perform operations on the array.
In each operation, you pick any nums[i]
and delete it to earn nums[i]
points. After, you must delete every element equal to nums[i] - 1
or nums[i] + 1
.
You start with 0 points. Return the maximum number of points you can earn by applying such operations.
Example 1:
Input: nums = [3, 4, 2] Output: 6 Explanation: Delete 4 to earn 4 points, consequently 3 is also deleted. Then, delete 2 to earn 2 points. 6 total points are earned.
Example 2:
Input: nums = [2, 2, 3, 3, 3, 4] Output: 9 Explanation: Delete 3 to earn 3 points, deleting both 2's and the 4. Then, delete 3 again to earn 3 points, and 3 again to earn 3 points. 9 total points are earned.
Note:
- The length of
nums
is at most20000
. - Each element
nums[i]
is an integer in the range[1, 10000]
.
Related Topics:
Dynamic Programming
Similar Questions:
Solution 1. DP
Firstly, to avoid duplicate, store the data in a map from the number to its count.
Let dp[i]
be the max point you can get at point i
.
If num != prevNum + 1
, we can freely pick num
, then dp[i] = dp[i-1] + num * count
.
Otherwise, if we don’t pick num
, dp[i] = dp[i-1]
.
Otherwise, we pick num
, dp[i] = dp[i-2] + num * count
.
So in sum:
dp[i] = num == prevNum ? max(dp[i-1], dp[i-2] + num * count) : (dp[i-1] + num * count)
// OJ: https://leetcode.com/problems/delete-and-earn/
// Time: O(NlogN)
// Space: O(N)
class Solution {
public:
int deleteAndEarn(vector<int>& nums) {
map<int, int> m;
for (int n : nums) m[n]++;
int prev = 0, prev2 = 0, num = INT_MIN;
for (auto &p : m) {
int cur = p.first == num + 1 ? max(prev, prev2 + p.first * p.second) : (prev + p.first * p.second);
prev2 = prev;
prev = cur;
num = p.first;
}
return prev;
}
};
-
class Solution { public int deleteAndEarn(int[] nums) { if (nums == null || nums.length == 0) return 0; if (nums.length == 1) return nums[0]; int max = 0; for (int num : nums) max = Math.max(max, num); int[] counts = new int[max + 1]; for (int num : nums) counts[num]++; int[] dp = new int[max + 1]; dp[1] = counts[1]; dp[2] = Math.max(dp[1], 2 * counts[2]); for (int i = 3; i <= max; i++) dp[i] = Math.max(dp[i - 1], dp[i - 2] + i * counts[i]); return dp[max]; } } ############ public class Solution { public int deleteAndEarn(int[] nums) { if (nums.length == 0) { return 0; } int[] sums = new int[10010]; int[] select = new int[10010]; int[] nonSelect = new int[10010]; int maxV = 0; for (int x : nums) { sums[x] += x; maxV = Math.max(maxV, x); } for (int i = 1; i <= maxV; i++) { select[i] = nonSelect[i - 1] + sums[i]; nonSelect[i] = Math.max(select[i - 1], nonSelect[i - 1]); } return Math.max(select[maxV], nonSelect[maxV]); } }
-
// OJ: https://leetcode.com/problems/delete-and-earn/ // Time: O(NlogN) // Space: O(N) class Solution { public: int deleteAndEarn(vector<int>& A) { map<int, int> m; for (int n : A) m[n]++; int prev = 0, prev2 = 0, num = INT_MIN; for (auto &[n, cnt] : m) { int cur = n == num + 1 ? max(prev, prev2 + n * cnt) : (prev + n * cnt); prev2 = prev; prev = cur; num = n; } return prev; } };
-
class Solution: def deleteAndEarn(self, nums: List[int]) -> int: mx = -inf for num in nums: mx = max(mx, num) total = [0] * (mx + 1) for num in nums: total[num] += num first = total[0] second = max(total[0], total[1]) for i in range(2, mx + 1): cur = max(first + total[i], second) first = second second = cur return second
-
func deleteAndEarn(nums []int) int { max := func(x, y int) int { if x > y { return x } return y } mx := math.MinInt32 for _, num := range nums { mx = max(mx, num) } total := make([]int, mx+1) for _, num := range nums { total[num] += num } first := total[0] second := max(total[0], total[1]) for i := 2; i <= mx; i++ { cur := max(first+total[i], second) first = second second = cur } return second }