题目:
给你一个整数数组 nums
,你可以对它进行一些操作。
每次操作中,选择任意一个 nums[i]
,删除它并获得 nums[i]
的点数。之后,你必须删除 所有 等于 nums[i] - 1
和 nums[i] + 1
的元素。
开始你拥有 0
个点数。返回你能通过这些操作获得的最大点数。
思路 :删除 所有 等于 nums[i] - 1
和 nums[i] + 1
的元素 不会获得点数(相当于打家劫舍)
看示例 2,nums=[2,2,3,3,3,4]。如果我们选了一个等于 3 的数,那么所有等于 2 和等于 4 的数都被删除,也就是都不能选。选了一个 3 后,剩下的 3 可以继续选。所以如果要选 3,所有的 3 都要选。这种「相邻数字不能都选」联想到 198. 打家劫舍。
把 nums 转换成一个值域数组a,其中a[i] 表示nums中的等于 i 的元素之和。上面的例子中,a=[0,0,4,9,4]。因为 nums 中有3个3,所以a[3]=3+3+3=9。计算数组a的 198. 打家劫舍,即为答案。
代码:
java
class Solution {
public int deleteAndEarn(int[] nums) {
int max = 0;
for (int num : nums) {
max = Math.max(max, num);
}
int[] a = new int[max + 1];
for (int x : nums) {
a[x] += x;
}
return rob(a);
}
private int rob(int[] nums) {
int f0 = 0;
int f1 = 0;
for (int x : nums) {
int newF = Math.max(f0 + x, f1);
f0 = f1;
f1 = newF;
}
return f1;
}
}
性能:
时间复杂度o(n + U) U=max(nums)
空间复杂度o(U)