【知识迁移】力扣刷题- 删除并获得点数(Python 实现)

快速通道

740. 删除并获得点数

前言

有些题目比较隐晦,拿到题目毫无头绪,又不像刷举一反三系列一样,由易到难,本文主要记录解题的思路。

740. 删除并获得点数

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

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

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

来源:力扣(LeetCode)

解题

拿到该题,再结合示例,发现就是我要取某个数,然后邻近的数都需要全部删除,并且求最大值,这种题目一般不可能枚举,一定有某种规律,而且求最大最小值,一般涉及贪心算法。
比如【1,1,2,2,2,3,3】,我如果取了一个2,就会把 1和3 全部删除,最后剩下 2,也就是说如果选择了2,最终结果是把2全部相加,邻近的1和3不能加,那也就是说我最终的结果其实是取某些特定数的总和,就比如以上序列,分别映射的的点数分别是 2,6,6,然后我要取求最大点数,到这里发现该题跟打家劫舍非常相似。
唯一的不同点便是打家劫舍是连续的数组,而这个显然不是,而本题非连续数字是可以相加的,那我只需要判断上一个数是不是比当前数少1 不就行了嘛。
步骤:
st1:计算每个数的点数总和(数的个数 * 点数)
st2:需要一个去重过的递增的序列,就像打家劫舍的索引序列一样
st3:先用动态规划做,创建一个dp数组,长度为 n 或者 n+1,我这里用的n,主要是这样子方便一点。
st4:然后遍历,需要分情况讨论,如果有序序列的上一个数 跟当前数不是连续的,那就直接加,要不然就分两种情况 取max。
st5:最后取出dp的最后一个位置的数,即为最终的结果。

class Solution:
    def deleteAndEarn(self, nums: List[int]) -> int:
        # 该题跟打家劫舍有点像
        numdict = dict()
        numlist = []
        for num in nums:
            if num in numdict.keys():
                numdict[num] += num
            else:
                numdict[num] = num
                numlist.append(num)
        # 然后用动态规划
        n = len(numlist)
        sortnuml = sorted(numlist)

        dp = [0] * (n + 1)
        dp[1] = numdict[sortnuml[0]]

        for i in range(1,n):
            # 如果上一个不是连续的
            if sortnuml[i] != sortnuml[i-1] + 1:
                dp[i+1] = dp[i] + numdict[sortnuml[i]]
            else:
                dp[i+1] = max(dp[i], dp[i-1] + numdict[sortnuml[i]])

        return dp[n]
总结

该题的关键是把相同数的点数相加,为什么要把相同数点数相加,有时候没有思路的时候可以试着举例找找规律。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值