备注:题目描述以及示例来自力扣 leetcode.cn/problems/de…
本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目描述
给你一个整数数组 nums ,你可以对它进行一些操作。每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。 开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。
示例1
输入:[3,4,2]
输出:6
解释:删除4获得4个点数,因为4-1==3,所以3被删除,之后删除2,获得2个点数,总共6个点数
示例2
输入:[2,2,3,3,3,4]
输出:9
解释:删除 3 获得 3 个点数,接着要删除两个 2 和 4 。之后,再次删除 3 获得 3 个点数,再次删除 3 获得 3 个点数。
总共获得 9 个点数。
思路:以数组[2,2,3,3,3,4]举例,我们如果拿到了2的点数,我们是可以拿到所有的2的点数的,就必须删掉所有的1和3
*我们可以使用一个新的数组:[0,0,4,9,4] 来对应原数组
原数没有值为0的元素,所以arr[0]=0;
原数组没有值为1的元素,所以arr[1]=0;
原数组值为2的元素有2个,所以arr[2]=4;
原数组值为3的元素有3个,所以arr[3]=9;
同理arr[4]=4
题目便可以分解为打家劫舍,不可以同时取相邻两个元素的值,最后计算累计最大值
解:
var deleteAndEarn = function (nums) {
let arr = new Array(Math.max.apply(Math, nums) + 1).fill(0) //1
let max = 0 //2
for (let i = 0; i < nums.length; i++) { //3
arr[nums[i]] = arr[nums[i]] + nums[i]
}
for (let i = 2; i < arr.length; i++) {
if(arr[i-2]>max) max = arr[i-2] //4
arr[i] = max + arr[i]
}
return Math.max(arr[arr.length - 1], arr[arr.length - 2]) //5
};
来做每一步的解释:
1.创建新数组arr,其长度与nums的最大值相关,arr元素各项设置为0
例: nums = [2,2,3,3,3,4] => arr = [0,0,0,0,0]
2.设置中间值max=0
3.对新数组进行填充,填充规则参考思路
例:nums = [3,4,2] => arr[3] = 3; arr[4] = 4; arr[2] = 2 ; => arr [ 0 , 0 , 2 , 3 , 4 ]
4.动态规划思想,我们要想获得点数的最大值,比如要向获得arr[i]的最大值,这个值肯定是(0,i-1)的最大值与arr[i]本身相加
例:在数组 a = [0,1,2,4,6,2] 得到 a[0,1,2,5,8,7]
5.输出得到数组最后两个元素的较大值