740. 删除并获得点数

236 阅读2分钟

这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战

740. 删除并获得点数

给你一个整数数组 nums ,你可以对它进行一些操作。

每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除每个等于 nums[i] - 1 或 nums[i] + 1 的元素。

开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。

示例 1:

输入:nums = [3,4,2] 输出:6 解释: 删除 4 获得 4 个点数,因此 3 也被删除。 之后,删除 2 获得 2 个点数。总共获得 6 个点数。

解题思路

根据题意,在选择了元素 x 后,该元素以及所有等于 x-1 或 x+1 的元素会从数组中删去。

因此我们将代码分为两个部分

  1. 统计每个元素出现的次数(方便计算删除元素后的得分),并且找出最大值(为了缩小dp数组的长度)
	for _, num := range nums {
		cnt[num]++
		if num>max{
			max=num
		}
	}
  1. 状态转移 dp[i][0]代表当前元素是i,并且不删除该元素。因此前一个元素可以是被删除元素,也可以不是 dp[i][1]代表当前元素是i,需要删除该元素。因此前一个元素必须不为删除元素(因为如果前一个元素是删除元素,该元素已经被删除掉了),并且加上删除后的得分
	for i := 1; i <= max; i++ {

		dp[i][0]=MaxV(dp[i-1][0],dp[i-1][1])
		dp[i][1]=dp[i-1][0]+i*cnt[i]
	}

代码

func MaxV (a int,b int) int {
	if a>b{
		return a
	}else {
		return b
	}
}
  

func deleteAndEarn(nums []int) int {
	cnt:=make([]int,10008)
	max:=-1
	for _, num := range nums {
		cnt[num]++
		if num>max{
			max=num
		}
	}
	dp:=make([][2] int,max+1)
	for i := 1; i <= max; i++ {

		dp[i][0]=MaxV(dp[i-1][0],dp[i-1][1])
		dp[i][1]=dp[i-1][0]+i*cnt[i]
	}
    return MaxV(dp[max][0],dp[max][1])
}

时间复杂度:O(N+M),其中 NN 是数组nums 的长度,M 是nums 中元素的最大值。

空间复杂度:O(M)。