#740 Delete and Earn

Description

You are given an integer array nums. You want to maximize the number of points you get by performing the following operation any number of times:

  • Pick any nums[i] and delete it to earn nums[i] points.

Afterwards, you must delete every element equal to nums[i] - 1 and every element equal to nums[i] + 1.
Return the maximum number of points you can earn by applying the above operation some number of times.

Examples

Example 1:

Input: nums = [3,4,2]
Output: 6
Explanation: You can perform the following operations:

  • Delete 4 to earn 4 points. Consequently, 3 is also deleted. nums = [2].
  • Delete 2 to earn 2 points. nums = [].
    You earn a total of 6 points.

Example 2:
Input: nums = [2,2,3,3,3,4]
Output: 9
Explanation: You can perform the following operations:

  • Delete a 3 to earn 3 points. All 2’s and 4’s are also deleted. nums = [3,3].
  • Delete a 3 again to earn 3 points. nums = [3].
  • Delete a 3 once more to earn 3 points. nums = [].
    You earn a total of 9 points.

Constraints:
1 <= nums.length <= 2 * 104
1 <= nums[i] <= 104

思路

这里有一个容易被忽视的点是,他并不是不能同时earn位置上相邻的两个数,而是不能同时earn数值上相邻的两个数
在知道了这点之后,其实就是一个简单的动态规划。

代码

class Solution {
    public int deleteAndEarn(int[] nums) {
        Arrays.sort(nums);
        int i = 0;
        int pre = Integer.MIN_VALUE;
        
        int[] answer = new int[nums.length];
        answer[0] = 0;
        int temp = nums[0];
        while(i < nums.length && nums[i] == temp){
            answer[0] += nums[i];
            i++;
        }
        if(i == nums.length)
            return answer[0];
        pre = nums[0];
        
        answer[1] = 0;
        temp = nums[i];
        while(i < nums.length && nums[i] == temp){
            answer[1] += nums[i];
            i++;
        }
        if(i == nums.length){
            if(nums[i - 1] == pre + 1)
                return Math.max(answer[0], answer[1]);
            else
                return answer[0] + answer[1];
        }
        if(nums[i - 1] == pre + 1)
            answer[1] = Math.max(answer[0], answer[1]);
        else
            answer[1] = answer[0] + answer[1];
        pre = nums[i - 1];   
        
        int step = 2;
        while(i < nums.length){
            int sum = 0;
            temp = nums[i];
            while(i < nums.length && nums[i] == temp){
                sum += nums[i];
                i++;
            }
            
            if(nums[i - 1] == pre + 1)
                answer[step] = Math.max(answer[step - 2] + sum, answer[step - 1]);
            else
                answer[step] = Math.max(answer[step - 2], answer[step - 1]) + sum;
            step++;
            pre = nums[i - 1];
        }
        
        return Math.max(answer[step - 1], answer[step - 2]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值