链接:740. 删除并获得点数 - 力扣(LeetCode)
题目:
给你一个整数数组
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 个点数。
思路:
若选择了多个值为 x 的元素,所有等于 x−1 或 x+1 的元素要被删除,同时要删除这多个x值并获得其点数。
先创建长度为数组中最大值+1的数组arr,将nums数组中的对应值x,加到arr[x]中去,得到的数组arr的每个值item为数组 nums 中所有相同元素item之和。
此时,这个题目就变成了打家劫舍题目,如[ 0, 0, 2, 3, 4 ]。
明白一个道理,前 i 个的最大点数为 如果前 i - 2 的最大点数加上第 i 个的点数大于前 i - 1 的最大点数,那么前 i 个的最大点数为前 i - 2 的最大点数加上第 i 个的点数,否则为前 i - 1 的最大点数。
每次循环开始时leftsum代表前 i - 2 的最大点数,sum代表前 i - 1 的最大点数。每次循环结束后leftsum代表前 i - 1 的最大点数,sum代表前 i 的最大点数。所有最后返回sum值。
代码:
/**
* @param {number[]} nums
* @return {number}
*/
var deleteAndEarn = function(nums) {
let max = 0
// 求出数组中的最大值
nums.forEach((value)=>{
max = value>max?value:max
})
// 创建长度为max+1的数组
let arr = new Array(max + 1).fill(0)
// 将所有相同元素的值加在一起
for(item of nums){
arr[item] += item
}
// 初始化
// leftsum为前0个的最大点数,sum为前1个的最大点数
let leftsum = 0 , sum = arr[1]
for(let i = 2 ; i < arr.length ; i++ ){
if(leftsum+arr[i]>sum) {
let item = sum
sum = leftsum + arr[i]
leftsum = item
}else{
leftsum = sum
}
}
return sum
};