Leecode 740.删除数并获取得点数
题目
-
给你一个整数数组 nums ,你可以对它进行一些操作。
-
每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。
-
开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。
示例
-
示例 1:
-
输入:nums = [3,4,2]
输出:6
解释:
删除 4 获得 4 个点数,因此 3 也被删除。之后,删除 2 获得 2 个点数。总共获得 6 个点数。
-
-
示例 2:
-
输入:nums = [2,2,3,3,3,4]
输出:9
解释:
删除 3 获得 3 个点数,接着要删除两个 2 和 4 。
之后,再次删除 3 获得 3 个点数,再次删除 3 获得 3 个点数。
总共获得 9 个点数。
-
-
提示:
-
1 <= nums.length <= 2 * 104
1 <= nums[i] <= 104
-
解题思路及算法详解
- 题目问获得最大点数:类似这样的题目可以使用 动态规划,贪心,深度优先搜索,暴力搜索,显然深度优先搜索和暴力的时间复杂度太高,题目要求最大数可以是104,会导致超出时间限制,那么就考虑用 贪心还是动态规划,对于贪心算法,取决于能不能找到局部最优解,递推到全局最优解,显然这个题目不满足,对于动态规划,取决于能不能找到动态转移方程,并且找到满足的**动态规划的三大步骤**
- 第一步骤:定义dp数组元素的含义
- 第二步骤:找出数组元素之间的关系式
- 第三步骤:找出初始值
- 首先这个题目表面上不好定义 数组元素,披着狼皮的动态规划,需要去发现,将题目的nums数组转变成dp数组,统计出每个相同nums[i]累加在一起,如果不理解可以参考Leecode 198.打家劫舍
代码实现Java
-
class Solution { public int deleteAndEarn(int[] nums) { int maxVal = 0; for (int val : nums) { maxVal = Math.max(maxVal, val); } int[] sum = new int[maxVal + 1]; for (int val : nums) { sum[val] += val; } int size = sum.length; int a = sum[0], b = Math.max(sum[0], sum[1]); for (int i = 2; i < size; i++) { int c = b; b = Math.max(a + sum[i], b); a = c; } return b; } }