力扣刷题笔记《动态规划篇》→ 740. 删除并获得点数

305 阅读1分钟

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

题目

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

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

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

示例

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

输入:nums = [2,2,3,3,3,4]
输出:9
解释:
删除 3 获得 3 个点数,接着要删除两个 2 和 4 。
之后,再次删除 3 获得 3 个点数,再次删除 3 获得 3 个点数。
总共获得 9 个点数。

提示

  • 1 <= nums.length <= 2 * 10410^4
  • 1 <= nums[i] <= 10410^4

解题思路

这道题的推到思路跟【198.打家劫舍】一样。

有不知道的小伙伴可以先看一下那一篇(我绝对不会说是为了增加阅读量)_{(我绝对不会说是为了增加阅读量)}

不同的地方在于,打家劫舍是每处房屋的价值已经是固定的了,而这道题需要我们在推导之前再做一次统计,对所有数值相同的元素进行统计,并排序,方便后面跳过前后相邻的元素。

1.gif

代码实现

class Solution {
    public int deleteAndEarn(int[] nums) {
        // 边界判断
        if(nums.length == 1){
            return nums[0];
        }

        // 得到数值区间
        int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
        for(int num : nums){
            if(max < num){
                max = num;
            }
            if(min > num){
                min = num;
            }
        }

        // 累加相同元素
        int[] counts = new int[max - min + 1];
        for(int num : nums){
            counts[num - min] += num;
        }

        // 状态转移:dp[i] = max(dp[i - 1], dp[i - 2] + counts[i])
        int front = counts[0], after = Math.max(counts[0], counts[1]);
        for(int i = 2; i <= max - min; ++i){
            int tmp = Math.max(after, front + counts[i]);
            front = after;
            after = tmp;
        }

        return after;
    }
}

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处:leetcode-cn.com/problems/de…