一、题意
给你一个整数数组 nums ,每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除所有等于 nums[i] - 1和 nums[i] + 1的元素。开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。
1
<
=
n
u
m
s
.
l
e
n
g
t
h
<
=
2
∗
1
0
4
1 <= nums.length <= 2*10^4
1<=nums.length<=2∗104
1
<
=
n
u
m
s
[
i
]
<
=
1
0
4
1 <= nums[i] <= 10^4
1<=nums[i]<=104
二、解法
1、因为nums的范围在int范围以内,所以用数组下标来表示nums的数值,用sum数组统计出nums数组中相同数字相加的结果(例如有3个3,则sum[3]=9)。
2、取sum[i],就不能取sum[i-1](类似198.打家劫舍),对于dp[i]:
d
p
[
i
]
=
m
a
x
(
d
p
[
i
−
1
]
,
d
p
[
i
−
2
]
+
s
u
m
[
i
]
)
dp[i]=max(dp[i-1],dp[i-2]+sum[i])
dp[i]=max(dp[i−1],dp[i−2]+sum[i])
三、代码
int deleteAndEarn(vector<int>& nums) {
int n=nums.size();
if(n==1){
return nums[0];
}
int maxNum=nums[0];
for(int val:nums){
maxNum = max(val,maxNum);
}
vector<int> sum(maxNum+1,0);
set<int> numSet;
for(int val:nums){
sum[val]+=val;
numSet.insert(val);
}
vector<int> dp(n,0);
int first = sum[0];
int second = max(sum[0],sum[1]);
for(int i=2;i<=maxNum;i++){
int temp = second;
second=max(second ,first+sum[i]);
first = temp;
}
return second;
}