(力扣---动态规划)删除与获得点数

(力扣—动态规划)删除与获得点数

问题描述

给定一个整数数组 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 个点数。

注意:
nums的长度最大为20000。
每个整数nums[i]的大小都在[1, 10000]范围内。

算法思想

这道题的核心思想是力扣之前的一道叫“打家劫舍”的题,这道题我之前也写过博客。链接如下:
打家劫舍问题
这里值得说明的是,这道题和打家劫舍唯一不同的是“连续情况”。打家劫舍问题“相邻就是连续”,但是这个问题必须数字相邻才相邻。我做的比较简单,把数字补充完整再用打家劫舍的思想去做就好了。
其实有时候我想,如果不是专门研究算法的 没有太大必要为了追求那一点效率弄得那么复杂。
就像python哲学中的一句话:Explicit is better than inexplicit.
哈哈 这里就说多了。
下面上代码:

python code
class Solution:
    def deleteAndEarn(self, nums: List[int]) -> int:
        if not nums: return 0
        comp_nums = [i for i in range(1, max(nums) + 1)]
        dicts = dict.fromkeys(comp_nums, 0)
        for i in nums:
            dicts[i] += 1
        a = b = 0
        keys = list(dicts.keys())
        for i in range(len(keys)):
            a, b = b, max(a + dicts[keys[i]] * keys[i], b)
        return b
c++ code
class Solution {
public:
    int deleteAndEarn(vector<int>& nums) {
        if(!nums.size()) return 0;
        sort(nums.begin(), nums.end());                 //先排序
        int maxF = nums[nums.size() - 1];               //获取最大值
        map<int, int> comp;                             //利用map构造一个完整的“打家劫舍模型”
        for(int i = 1; i <= maxF; i++)
            comp[i] = 0;
        for(int temp: nums)
            comp[temp]++;
        int a = 0;
        int b = 0;
        for(map<int, int>::iterator it = comp.begin(); it != comp.end(); it++){
            int temp = b;
            b = max(a + it->first * it->second, b);
            a = temp;
        }
        return b;
    }
};

下面想分享下大牛Tim Peters所讲的python哲学
输入:
import this
然后会弹出:

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值