---
tags: leetcode
---
# [740. Delete and Earn](https://leetcode.com/problems/delete-and-earn/)
---
# My Solution
## Solution 1: Brute force (TLE)
### The Key Idea for Solving This Coding Question
### C++ Code
```cpp=
class Solution {
public:
int deleteAndEarn(vector<int> &nums) {
// Find the maximum number in nums.
int maxNum = 0;
for (auto &num : nums) {
if (maxNum < num) {
maxNum = num;
}
}
// We want to sort nums but we don't use sorting algorithm.
// We use another array, values, to accumulate the all the
// numbers in nums. For example, if nums = [2,2,3,3,3,4],
// values will be [0,0,4,9,4].
// Therefore, values[nums[i]] = nums[i] * n, for n is the
// number of occurences of nums[i].
// Because the 1 <= nums[0] <= 10^4, values[0] is always zero.
vector<int> values(maxNum + 1, 0);
for (auto &num : nums) {
values[num] += num;
}
return getMaxPoints(values, values.size() - 1);
}
private:
// getMaxPoints returns the maximum points from values[1..i].
int getMaxPoints(vector<int> &values, int i) {
if (i == 0) {
// base case 1:
// Because 0 is not valid in nums, it gains zero points.
return values[0];
}
if (i == 1) {
// base case 2:
// Because 1 is the smallest valid number in nums, the
// maximum points we can get is values[1].
return values[1];
}
return max(getMaxPoints(values, i - 1), getMaxPoints(values, i - 2) + values[i]);
}
};
```
### Time Complexity
$O(n + 2^{maxNum})$
$n$ is the length of `nums`.
$maxNum$ is the maximum number in `nums`.
### Space Complexity
$O(maxNum)$
## Solution 2: Top-down DP
### The Key Idea for Solving This Coding Question
### C++ Code 1
```cpp=
class Solution {
public:
int deleteAndEarn(vector<int> &nums) {
// Find the maximum number in nums.
int maxNum = 0;
for (auto &num : nums) {
if (maxNum < num) {
maxNum = num;
}
}
// We want to sort nums but we don't use sorting algorithm.
// We use another array, values, to accumulate the all the
// numbers in nums. For example, if nums = [2,2,3,3,3,4],
// values will be [0,0,4,9,4].
// Therefore, values[nums[i]] = nums[i] * n, for n is the
// number of occurences of nums[i].
// Because the 1 <= nums[0] <= 10^4, values[0] is always zero.
vector<int> values(maxNum + 1, 0);
for (auto &num : nums) {
values[num] += num;
}
// memo[i] is the maximum points we can get from nums[1..i].
unordered_map<int, int> memo;
// Base case 1:
// 0 is not a valid number in numbers, we can get 0 point.
memo[0] = 0;
// Base case 2:
// 1 is the smallest valid number in nums. If there are only 1
// in nums, values[1] is the maximum points.
memo[1] = values[1];
return getMaxPoints(values, memo, values.size() - 1);
}
private:
// getMaxPoints returns the maximum points from values[1..i].
int getMaxPoints(vector<int> &values, unordered_map<int, int> &memo, int i) {
auto iter = memo.find(i);
if (iter != memo.end()) {
return iter->second;
}
return memo[i] = max(getMaxPoints(values, memo, i - 1),
getMaxPoints(values, memo, i - 2) + values[i]);
}
};
```
### C++ Code 2
```cpp=
class Solution {
public:
int deleteAndEarn(vector<int> &nums) {
// Find the maximum number in nums.
int maxNum = 0;
for (auto &num : nums) {
if (maxNum < num) {
maxNum = num;
}
}
// We want to sort nums but we don't use sorting algorithm.
// We use another array, values, to accumulate the all the
// numbers in nums. For example, if nums = [2,2,3,3,3,4],
// values will be [0,0,4,9,4].
// Therefore, values[nums[i]] = nums[i] * n, for n is the
// number of occurences of nums[i].
// Because the 1 <= nums[0] <= 10^4, values[0] is always zero.
vector<int> values(maxNum + 1, 0);
for (auto &num : nums) {
values[num] += num;
}
// memo[i] is the maximum points we can get from nums[1..i].
vector<int> memo(maxNum + 1, -1);
// Base case 1:
// 0 is not a valid number in numbers, we can get 0 point.
memo[0] = 0;
// Base case 2:
// 1 is the smallest valid number in nums. If there are only 1
// in nums, values[1] is the maximum points.
memo[1] = values[1];
return getMaxPoints(values, memo, values.size() - 1);
}
private:
// getMaxPoints returns the maximum points from values[1..i].
int getMaxPoints(vector<int> &values, vector<int> &memo, int i) {
if (memo[i] >= 0) {
return memo[i];
}
return memo[i] = max(getMaxPoints(values, memo, i - 1),
getMaxPoints(values, memo, i - 2) + values[i]);
}
};
```
### Time Complexity
$O(n + maxNum)$
$n$ is the length of `nums`.
$maxNum$ is the maximum number in `nums`.
### Space Complexity
$O(maxNum)$
## Solution 3: Buttom-up DP
### The Key Idea for Solving This Coding Question
### C++ Code
```cpp=
class Solution {
public:
int deleteAndEarn(vector<int> &nums) {
// Find the maximum number in nums.
int maxNum = 0;
for (auto &num : nums) {
if (maxNum < num) {
maxNum = num;
}
}
// We want to sort nums but we don't use sorting algorithm.
// We use another array, values, to accumulate the all the
// numbers in nums. For example, if nums = [2,2,3,3,3,4],
// values will be [0,0,4,9,4].
// Therefore, values[nums[i]] = nums[i] * n, for n is the
// number of occurences of nums[i].
// Because the 1 <= nums[0] <= 10^4, values[0] is always zero.
vector<int> values(maxNum + 1, 0);
for (auto &num : nums) {
values[num] += num;
}
// dp[i] is the maximum points we can get from nums[1..i].
vector<int> dp(maxNum + 1, -1);
// Base case 1:
// 0 is not a valid number in numbers, we can get 0 point.
dp[0] = 0;
// Base case 2:
// 1 is the smallest valid number in nums. If there are only 1
// in nums, values[1] is the maximum points.
dp[1] = values[1];
for (int i = 2; i <= maxNum; ++i) {
dp[i] = max(dp[i - 1], dp[i - 2] + values[i]);
}
return dp[maxNum];
}
};
```
### Time Complexity
$O(n + maxNum)$
$n$ is the length of `nums`.
$maxNum$ is the maximum number in `nums`.
### Space Complexity
$O(maxNum)$
## Solution 4: Buttom-up DP (no DP array)
### The Key Idea for Solving This Coding Question
### C++ Code
```cpp=
class Solution {
public:
int deleteAndEarn(vector<int> &nums) {
// Find the maximum number in nums.
int maxNum = 0;
for (auto &num : nums) {
if (maxNum < num) {
maxNum = num;
}
}
// We want to sort nums but we don't use sorting algorithm.
// We use another array, values, to accumulate the all the
// numbers in nums. For example, if nums = [2,2,3,3,3,4],
// values will be [0,0,4,9,4].
// Therefore, values[nums[i]] = nums[i] * n, for n is the
// number of occurences of nums[i].
// Because the 1 <= nums[0] <= 10^4, values[0] is always zero.
vector<int> values(maxNum + 1, 0);
for (auto &num : nums) {
values[num] += num;
}
// Base case 1:
// 0 is not a valid number in numbers, we can get 0 point.
int dp0 = 0;
// Base case 2:
// 1 is the smallest valid number in nums. If there are only 1
// in nums, values[1] is the maximum points.
int dp1 = values[1];
int dp2 = max(dp0, dp1);
for (int i = 2; i <= maxNum; ++i) {
dp2 = max(dp1, dp0 + values[i]);
dp0 = dp1;
dp1 = dp2;
}
return dp2;
}
};
```
### Time Complexity
$O(n + maxNum)$
$n$ is the length of `nums`.
$maxNum$ is the maximum number in `nums`.
### Space Complexity
$O(maxNum)$
# Miscellaneous
<!--
# Test Cases
```
[3,4,2]
```
```
[2,2,3,3,3,4]
```
```
[1]
```
```
[5,3,2,4,5,6,7,2,2,1,10000]
```
* Time Limit Error:
```
[12,32,93,17,100,72,40,71,37,92,58,34,29,78,11,84,77,90,92,35,12,5,27,92,91,23,65,91,85,14,42,28,80,85,38,71,62,82,66,3,33,33,55,60,48,78,63,11,20,51,78,42,37,21,100,13,60,57,91,53,49,15,45,19,51,2,96,22,32,2,46,62,58,11,29,6,74,38,70,97,4,22,76,19,1,90,63,55,64,44,90,51,36,16,65,95,64,59,53,93]
```
-->