[LeetCode] Delete and Earn 删除与赚取
Given an array nums of integers, you can perform operations on the array.
In each operation, you pick any nums[i] and delete it to earn nums[i] points. After, you must delete everyelement equal to nums[i] - 1 or nums[i] + 1.
You start with 0 points. Return the maximum number of points you can earn by applying such operations.
Example 1:
Input: nums = [3, 4, 2]
Output: 6
Explanation:
Delete 4 to earn 4 points, consequently 3 is also deleted.
Then, delete 2 to earn 2 points. 6 total points are earned.
Example 2:
Input: nums = [2, 2, 3, 3, 3, 4]
Output: 9
Explanation:
Delete 3 to earn 3 points, deleting both 2's and the 4.
Then, delete 3 again to earn 3 points, and 3 again to earn 3 points.
9 total points are earned.
Note:
- The length of
numsis at most20000. - Each element
nums[i]is an integer in the range[1, 10000].
博主浪了整整一个圣诞假期,现在也该收收心了,2018了,今年对于博主是很关键的一年,有太多的事情要去做,各种小目标需要完成,还有梦想去追逐,又要开始努力啦~在博主停更的这一周半的时间内,收到了网友们的私信和留言催更,请大家放心,2018年博主会继续坚持下去,继续追赶进度,虽然一直都没有完全追上-.-|||,照LeetCode这出题速度,今年题号有望突破一千大关啊,感觉碉堡了有木有,一起为了幸福而奋斗吧~
好了,来做题吧。这道题给了我们一个数组,每次让我们删除一个数字,删除的数字本身变为了积分累积,并且要同时移除之前数的加1和减1的数,但此时移除的数字不累计积分,让我们求最多能获得多少积分。博主最开始尝试的方法是积分大小来排列,先删除大的数字,但是不对。于是乎,博主发现相同的数字可以同时删除,于是就是建立了每个数字和其出现次数之间的映射,然后放到优先队列里,重写排序方式comparator为数字乘以其出现次数,先移除能产生最大积分的数字,可是还是不对。其实这道题跟之前那道House Robber的本质是一样的,那道题小偷不能偷相邻的房子,这道题相邻的数字不能累加积分,是不是一个道理?那么对于每一个数字,我们都有两个选择,拿或者不拿。如果我们拿了当前的数字,我们就不能拿之前的数字(如果我们从小往大遍历就不需要考虑后面的数字),那么当前的积分就是不拿前面的数字的积分加上当前数字之和。如果我们不拿当前的数字,那么对于前面的数字我们既可以拿也可以不拿,于是当前的积分就是拿前面的数字的积分和不拿前面数字的积分中的较大值。这里我们用take和skip分别表示拿与不拿上一个数字,takei和skipi分别表示拿与不拿当前数字,每次更新完当前的takei和skipi时,也要更新take和skip,为下一个数字做准备,最后只要返回take和skip中的较大值即可,参见代码如下:
解法一:
class Solution {
public:
int deleteAndEarn(vector<int>& nums) {
vector<int> sums(, );
int take = , skip = ;
for (int num : nums) sums[num] += num;
for (int i = ; i < ; ++i) {
int takei = skip + sums[i];
int skipi = max(skip, take);
take = takei; skip = skipi;
}
return max(skip, take);
}
};
下面这种解法直接使用sums数组来更新,而没有使用额外的变量。上面解法中没有讲解这个sums数组,这里的sums实际上相当于建立了数字和其总积分的映射,这里的总积分的计算方法是由数字乘以其出现次数得来的。由于题目中说了每个数字不会超过10000,所以sums的长度可以初始化为10001,然后遍历原数组,将遇到的数字都累加到该数字在数组中的位置上。然后从sums数组的第三个数字开始遍历,更新方法跟上面解法的思路很类似,当前的sums[i]值就等于前一个值sums[i-1]和前两个值sums[i-2]加上当前的sums[i]值中的较大值,其实思想就是在不拿当前数的积分,跟不拿前一个数的积分加上当前的积分之和,取二者中的较大值更新当前值sums[i],参见代码如下:
解法二:
class Solution {
public:
int deleteAndEarn(vector<int>& nums) {
vector<int> sums(, );
for (int num : nums) sums[num] += num;
for (int i = ; i < ; ++i) {
sums[i] = max(sums[i - ], sums[i - ] + sums[i]);
}
return sums[];
}
};
类似题目:
参考资料:
https://discuss.leetcode.com/topic/112807/java-c-clean-code-with-explanation
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Delete and Earn 删除与赚取的更多相关文章
- [LeetCode]Delete and Earn题解(动态规划)
Delete and Earn Given an array nums of integers, you can perform operations on the array. In each op ...
- [LeetCode] Delete Duplicate Emails 删除重复邮箱
Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique ...
- delete 多表删除的使用(连表删除)
delete 多表删除的使用 1.从数据表t1中把那些id值在数据表t2里有匹配的记录全删除掉 DELETE t1 FROM t1,t2 WHERE t1.id=t2.id 或 DELETE ...
- JAVA insert() 插入字符串 reverse() 颠倒 delete()和deleteCharAt() 删除字符 replace() 替换 substring() 截取子串
insert() 插入字符串 StringBuffer insert(int index,String str) StringBuffer insert(int index,char ch) Stri ...
- 用delete和trancate删除表记录的区别
首先说相同点,就是他们都能删除表中的数据,区别有两点: 第一点: delete语句在删除记录的时候可以有选择的删除某些数据(使用where子句),当然,如果不添加where子句,就是删除所有记录 而t ...
- LC 740. Delete and Earn
Given an array nums of integers, you can perform operations on the array. In each operation, you pic ...
- delete 和 splice 删除数组中元素的区别
delete 和 splice 删除数组中元素的区别 ` var arr1 = ["a","b","c","d"]; d ...
- 【python】Leetcode每日一题-删除有序数组中的重复项
[python]Leetcode每日一题-删除有序数组中的重复项 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现一次 ,返回删除后数组的新长度. 不要 ...
- 【python】Leetcode每日一题-删除有序数组中的重复项2
[python]Leetcode每日一题-删除有序数组中的重复项2 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不 ...
随机推荐
- C++ STL 容器之栈的使用
Stack 栈是种先进后出的容器,C++中使用STL容器Stack<T> 完美封装了栈的常用功能. 下面来个demo 学习下使用栈的使用. //引入IO流头文件 #include<i ...
- shell队列实现线程并发控制(转)
需求:并发检测1000台web服务器状态(或者并发为1000台web服务器分发文件等)如何用shell实现? 方案一:(这应该是大多数人都第一时间想到的方法吧) 思路:一个for循环1000次,顺序执 ...
- shell之九九乘法表
echo -n 不换行输出 $echo -n "123" $echo "456" 最终输出 123456 而不是 123 456 echo - ...
- 玩转接口测试工具fiddler 教程系列1
我们在做web测试的时候,很多时候需要查看接口发送的数据返回的数据是否正常,这样可以排除是客户端的问题还是服务器的问题,举个例子来说,如果我们发现页面上面数据少了, 通过fiddler查看数据返回就少 ...
- Leetcode 35——Search Insert Position
Given a sorted array and a target value, return the index if the target is found. If not, return the ...
- 那些在django开发中遇到的坑
1. 关于csrf错误 CSRF(Cross-site request forgery)跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或 ...
- pymysql 多字段插入
d = {'name':'alx','age':18,'pp':11,'cc':12} sql = '''insert into xx(%s) value(%s)''' key_list = [] v ...
- Java代码风格和在idea中的一些设置
源文件基本设置 1. 文件名 驼峰标识,.java结尾 2. 编码 统一为UTF-8 Transport...可以解决property文件不能正常显示为中文的问题 3. 特殊字符 尽量使用转义字符(\ ...
- 用java写一个servlet,可以将放在tomcat项目根目录下的文件进行下载
用java写一个servlet,可以将放在tomcat项目根目录下的文件进行下载,将一个完整的项目进行展示,主要有以下几个部分: 1.servlet部分 Export 2.工具类:TxtFileU ...
- css3动画transition详解
一.transition-property 语法: transition-property : none | all | [ <IDENT> ] [ ',' <IDENT> ] ...