740. 删除并获得点数 [中等]

151 阅读1分钟

题目

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

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

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

  • 来源:力扣(LeetCode)
  • 链接:leetcode-cn.com/problems/de…
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法

思路

看到这个题,直接懵圈。传言跟 打家劫舍 是一个题。怎么看怎么不像!

获得点数nums[i]之后,要求删除nums[i]-1和nums[i]+1的所有数字。也就是相邻的数字不能重复获取。

但是这些数字也没有排序,也有可能重复。怎么用动态规划的递推公式?

将nums[i]的数字映射成数组下标,该数组下标的内容为nums[i]所有出现的总和。因为,取了nums[i],那么所有和nums[i]相等的都可以取。

代码

    public int deleteAndEarn(int[] nums) {
        int max = nums[0];
        int n = nums.length;
        for (int i = 1; i < n; i++) {
            max = Math.max(max, nums[i]);
        }
        int[] sum = new int[max+1];
        for (int i = 0; i < n; i++) {
            sum[nums[i]] += nums[i];
        }
        
        int[] dp = new int[max+1];
        dp[0] = sum[0];
        dp[1] = Math.max(sum[0], sum[1]);
        for (int i = 2; i < max + 1; i++) {
            dp[i] = Math.max(dp[i-1], dp[i-2] + sum[i]);
        }
        return dp[max];
    }