其他分享
首页 > 其他分享> > 740. 删除并获得点数(LeetCode每日一题)

740. 删除并获得点数(LeetCode每日一题)

作者:互联网

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

题目链接:https://leetcode-cn.com/problems/delete-and-earn
难度:中等

1.题目

给你一个整数数组 nums ,你可以对它进行一些操作。
每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除每个等于 nums[i] - 1 或 nums[i] + 1 的元素。
开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数

2.示例

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

3.题解

思路:对于求最值的问题,一般使用动态规划解决。在取任意一个数的时候,我们应该尽可能多的将所有相同的数都取出来,这样有利于我们计算最大和。由于对于nums数组我们并不知道其中相同元素的个数,所以我们可以建一个新数组count来存储在对应下标下的数在nums中的个数。其长度等于nums数值中的最大值+1。
对此,我们设f[i]表示在最大值为i时,数组能获得的最大点数。则f[i] = Max{f[i-2]+count[i]*i,f[i-1]}(i>2)。

class Solution {
    public int deleteAndEarn(int[] nums) {
        int n = nums.length;
        int maxVal=0;
        //循环获取最大值
        for(int i=0;i<n;i++){
            maxVal=maxVal<nums[i]?nums[i]:maxVal;
        }
        int[] count = new int[maxVal+1];
        //将数组nums中的数填入对应下标的count数组
        for(int i=0;i<n;i++){
            count[nums[i]]++;  
        }
        return dp(count);
    }
    
    public int dp(int[] count){
        int n = count.length;
        int[] f = new int[n];
        //满足方程的数组i>2,则我们需要考虑在i<=2时的特殊情况
        f[1] = count[1]*1;
        if(n>2) f[2] = Math.max(f[1],count[2]*2);
        for(int i=3;i<n;i++){
            f[i] = 0;
            f[i] = Math.max(f[i-2]+count[i]*i,f[i-1]);
        }
        return f[n-1];
    }
}

复杂度分析
时间复杂度:O(N+M)
空间复杂度:O(M)
N表示数组nums的长度,M表示数组中元素的最大值。

4.总结

对于动态规划问题,需要先考虑转换方程,在考虑特殊情况。编写代码时思路就会清晰许多。

标签:740,count,删除,nums,int,数组,点数,LeetCode
来源: https://blog.csdn.net/weixin_46862463/article/details/116422708