ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[LeetCode] 740. Delete and Earn

2022-03-05 15:01:14  阅读:157  来源: 互联网

标签:740 Earn 删除 nums int max earn points LeetCode


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.

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

删除并获得点数。

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

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

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

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

这道题很像198题 house robber,思路是动态规划。这里我引用一个我看到的很好的思路。根据题意,对于任何一个 nums[i] 而言,如果你选择了它,那么 nums[i - 1] 和 nums[i + 1] 都不能选且只能被直接删除,这个题设很像 house robber。获得点数的规则是如果你删除 nums[i],那么你获得的点数是 nums[i]。如果我们将数组排好序从前往后处理,其实只需要考虑当前数字之前一个数字。所以我们首先用一个 count 数组记录一下每个数字的出现次数和出现数字的最大值。接着我们再创建一个二维的 DP 数组,记录每个数字选和不选的DP值。

对于当前的数字 i,

  • 如果我选择删除 i,我的收益是不删除前一个数字 dp[i - 1][0] 获得的收益 + 删除当前数字的收益 i * counts[i]
  • 如果我选择不删除 i,我的收益是删除和不删除前一个数字的收益的较大值

最后返回最后一个数字的DP值。

时间O(n)

空间O(n^2)

Java实现

 1 class Solution {
 2     public int deleteAndEarn(int[] nums) {
 3         int[] counts = new int[10001];
 4         int max = 0;
 5         for (int num : nums) {
 6             counts[num]++;
 7             max = Math.max(max, num);
 8         }
 9 
10         int[][] dp = new int[max + 1][2];
11         for (int i = 1; i <= max; i++) {
12             dp[i][1] = dp[i - 1][0] + i * counts[i];
13             dp[i][0] = Math.max(dp[i - 1][1], dp[i - 1][0]);
14         }
15         return Math.max(dp[max][0], dp[max][1]);
16     }
17 }

 

我这里提供另一种做法,思路也是DP,代码写的跟 house robber 很像。初始值是 first 和 second,first 是删除第一个元素的收益(偷第一个房子的收益),second 是不删除第一个元素删除第二个元素的收益(不偷第一个房子但是偷第二个房子的收益)。这里我们首先需要用一个数组 sum 记录偷每一个房子的收益。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int deleteAndEarn(int[] nums) {
 3         int max = 0;
 4         for (int num : nums) {
 5             max = Math.max(max, num);
 6         }
 7 
 8         // sum数组记录的是相同元素之和,比如有4个2的话,sum[2] = 8
 9         int[] sum = new int[max + 1];
10         for (int num : nums) {
11             sum[num] += num;
12         }
13         return rob(sum);
14     }
15 
16     public int rob(int[] nums) {
17         int len = nums.length;
18         int first = nums[0];
19         int second = Math.max(nums[0], nums[1]);
20         for (int i = 2; i < len; i++) {
21             int temp = second;
22             second = Math.max(first + nums[i], second);
23             first = temp;
24         }
25         return second;
26     }
27 }

 

相关题目

198. House Robber

740. Delete and Earn

LeetCode 题目总结

标签:740,Earn,删除,nums,int,max,earn,points,LeetCode
来源: https://www.cnblogs.com/cnoodle/p/15968038.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有