LeetCode740. 删除并获得点数

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode740. 删除并获得点数相关的知识,希望对你有一定的参考价值。

LeetCode740. 删除并获得点数

2021.5.5每日一题,动态规划,我的思路如下

class Solution {
    public int deleteAndEarn(int[] nums) {
        //看到题想到了动态规划,但是怎么规又是个问题,先排序应该没问题
        //dp[i]定义为到当前为止,删除数获得的最大点数
        //先举例想想,如果2是第一个数,删除一个2,到目前为止的点数为dp[2] = 2的数量×2
        //然后删除3,dp[3] = 3 的数量×3 + dp[1],不删除3,那么就是dp[2]
        //dp[4] = 4 的数量×4 + dp[2]
        //想到这里,突然想到一个问题,那数不是连续的该怎么办呢,如果是一个单独的数,删了就是最大了
        //所以先找出数组中最大的数,然后挨个删,删除每个数字的值用一个数组记录下来,然后直接计算就行
        //没有的数就是0,这样也不用排序了

        int l = nums.length;
        int maxNum = 0;
        for(int num : nums){
            maxNum = Math.max(maxNum, num);
        }
        //0 到 最大值
        int[] sum_num = new int[maxNum + 1];
        //例如,要删除3,获得的点数就是3的数量乘以3
        for(int num : nums){
            sum_num[num] += num;
        }

        //从0到maxNum删除
        int[] dp = new int[maxNum + 1];
        //初始化
        dp[0] = 0;
        dp[1] = sum_num[1];
        for(int i = 2; i <= maxNum; i++){
            dp[i] = Math.max(dp[i - 1], dp[i - 2] + sum_num[i]);
        }

        return dp[maxNum];
    }
}

看了答案,官解中还有把整个数组分成一个个小的连续的数组,然后再套用打家劫舍的方法,然后按着这个分组的思路,又写了一个代码,有点繁琐,不过思路没问题

class Solution {
    public int deleteAndEarn(int[] nums) {
        //看了答案,或者这样,就是相当于分成一个个连续子数组吧,先排序,当下一个数和当前数相差1的时候,就和打家劫舍一样转移
        //不连续的时候,那就直接删了
        Arrays.sort(nums);
        int l = nums.length;
        //统计每个数字的个数
        Map<Integer, Integer> map = new HashMap<>();

        for(int num : nums){
            map.put(num, map.getOrDefault(num, 0) + 1);
        }
        
        //前面补个0,防止边界的判断
        int[] dp = new int[map.size() + 1];
        int index = 2;
        dp[0] = 0;
        dp[1] = nums[0] * map.get(nums[0]);
        for(int i = 1; i < l; i++){
            //如果两个数相同,跳过
            if(nums[i] == nums[i - 1])
                continue;
            else if(nums[i] - 1 == nums[i - 1]){
                dp[index] = Math.max(dp[index - 1], dp[index - 2] + nums[i] * map.get(nums[i]));
                index++;
            }
            else{
                dp[index] = dp[index - 1] + nums[i] * map.get(nums[i]);
                index++;
            }
        }
        return dp[--index];
    }
}

以上是关于LeetCode740. 删除并获得点数的主要内容,如果未能解决你的问题,请参考以下文章

leetcode740. 删除并获得点数(线性相邻dp问题)

LeetCode740. 删除并获得点数(java/c++动态规划)

java刷题--740删除并获得点数

740. 删除并获得点数(dp)

740. 删除并获得点数(dp)

740. 删除并获得点数