给你一个整数数组 nums
,你可以对它进行一些操作。
每次操作中,选择任意一个 nums[i]
,删除它并获得 nums[i]
的点数。之后,你必须删除 所有 等于 nums[i] - 1
和 nums[i] + 1
的元素。
开始你拥有 0
个点数。返回你能通过这些操作获得的最大点数。
示例 1:
输入:nums = [3,4,2] 输出:6 解释: 删除 4 获得 4 个点数,因此 3 也被删除。 之后,删除 2 获得 2 个点数。总共获得 6 个点数。
示例 2:
输入:nums = [2,2,3,3,3,4] 输出:9 解释: 删除 3 获得 3 个点数,接着要删除两个 2 和 4 。 之后,再次删除 3 获得 3 个点数,再次删除 3 获得 3 个点数。 总共获得 9 个点数。
提示:
1 <= nums.length <= 2 * 104
1 <= nums[i] <= 104
解析:
这道题相当于当你选定一个数时,你左右两侧-1,+1的两个数都不能选了,所以,设置一个dp数组,长度为nums数组中的最大值,存储在nums数组中出现的相同元素之和,然后判断dp[i - 1]
+dp[i + 1]
和dp[i]
的大小关系,取最大值进行保留,这样这个最大值就相当于nums中,所有小于i的数,所能删除的最大点数。
源码:
class Solution {
public:
int rob(vector<int>& dp) {
int number1 = dp[0], number2 = max(dp[0], dp[1]);
for (int i = 2; i < dp.size(); i++) {
int temp = number2;
number2 = max(number1 + dp[i], number2);
number1 = temp;
}
return number2;
}
int deleteAndEarn(vector<int>& nums) {
int max_value = 0;
for (int val : nums) {
max_value = max(val, max_value);
}
vector<int> dp(max_value + 1, 0);
for (int val : nums) {
dp[val] += val;
}
return rob(dp);
}
};