题目链接: leetcode.cn/problems/de…
题目描述:
给你一个整数数组 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 * 1041 <= nums[i] <= 104
题目解析
如果选择 nums[i]就要删除 nums[i] - 1、nums[i] + 1 ,着看着是不是很熟悉,如果我这样摆放 nums[i] - 1、nums[i]、nums[i] + 1,再换一种说法,如果选择 nums[i]就不能选择 nums[i - 1]、nums[i + 1]。其实这里的不能选择和删除是一样的道理,一定要删除吗?不选择一样是删除。想要把他转换成《打家劫舍Ⅱ》的套路。这就需要初始化一下题目给定的参数了。 题目中给了一个 nums 数组,我们需要再创建一个数组 arr[10001]用来统计 nums 中的所有点数。我们使用 arr[sums[i]]来统计 sums[i]的所有点数。比如说 sums[i] = 2,且数组中有 3 个 2。那么我们就将 arr[2] = 6;来统计 2 累计的所有点数,然后当选择 2 的时候,就不能选择 arr[1] 和 arr[3]。下面就和打家劫舍一样了。
代码
class Solution {
public int deleteAndEarn(int[] nums) {
int n = 10001;
int[] arr = new int[n];
for (int i : nums) {
arr[i] += i;
}
int[] t = new int[n];
int[] f = new int[n];
t[0] = arr[0];
for (int i = 1; i < n; i++) {
t[i] = f[i - 1] + arr[i];
f[i] = Math.max(f[i - 1], t[i - 1]);
}
return Math.max(t[n - 1], f[n - 1]);
}
}