leetcode笔记|第六周 贪心专题

第六周 贪心专题

122 买卖股票的最佳时机 II

[7,1,5,3,6,4] 2号买入3号卖出赚4,3买入6卖出赚3。买入后只能卖出不能买入。虽然题目说不可以一天内多次操作,但写代码是可以的,这不会影响最终结果。因此考虑,[1,2,3]不仅是1号买入3号卖出,也可以是1号买入2号卖出2号买入3号卖出,这样就可以使用遍历。

看到答案里最简单的方法:一行python解决。可以细化到相邻两天的差价,正则赚,进行操作,负则不操作,即记录正值的和。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        return sum(b-a for a,b in zip(prices, prices[1:]) if b>a)

134 加油站

环路,n个加油站点存储着油,过去要消耗油。注意要遍历可以使用余数!当cur+1=start时遍历结束。如果当前节点到不了下一个,就把起点往前挪一个。不然就加油进入下一个。返回时考虑能否到起点,这是个坑。

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        n = len(gas)
        start, cur = 0, 0
        oil = gas[0]
        while (cur + 1) % mod != start:
            if oil < cost[cur]:
                start = (start - 1) % n
                oil += gas[start] - cost[start]
            else:
                oil -= cost[cur]
                cur = (cur + 1) % n
                oil += gas[cur]
        return start if oil - cost[cur] >= 0 else -1

55 跳跃游戏

一个数组,每个数值代表当前位置最大跳跃距离,判断能否跳到最后。贪心:希望跳到最远的地方。注意,能够达到某处,则前面的位置一定能够到达。所以,存储当前能够到达的最远距离,与最终结果位置做比较,如果maxDist比len(nums)-1也就是最后一个元素的位置还远,那么就能到终点。

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        if nums==[0]: return True
        terminal = len(nums)-1
        maxDist = 0
        for i, jump in enumerate(nums):
            if i <= maxDist and i+jump > maxDist:
                maxDist = i+jump
                if maxDist >= terminal:
                    return True
        return False

435 无重叠区间

[[1,2],[2,3],[1,3]]时删除第三个元素可以得到无重叠区间的最长子序列。要返回需要删除元素的最少个数,所以贪心算法,尽量保留跨度小,或者说右侧数字较小的元素,因此需要对右侧数字进行排序。排序后如果下一个元素开始数字比当前元素结束数字小则删掉,或者说反向思考,下一个元素起点比当前的终点大于等于才保留。

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        n = len(intervals)
        save = 0
        intervals.sort(key=lambda x:x[1])
        end = -float('inf')
        for interval in intervals:
            start = interval[0]
            if start >= end:
                save += 1
                end = interval[1]
        return n-save

406 根据身高重建队列

没看懂题目

649 Dota2参议院

'RD’互ban,则RbanD,则R胜。‘RDD’则D胜。贪心算法:己方ban的权利碰到敌方的时候就使用 先后使用结果一样 那么无限循环直到只有一方那就结束了。

class Solution:
    def predictPartyVictory(self, senate: str) -> str:
        senate = list(senate)	# list才可在后面赋值,改变元素
        people = 0 # 通过正负分辨两方
        Radiant, Dire = True, True
        while Radiant and Dire: # 直至一方阵亡
            Radiant, Dire = False, False
            for i in range(len(senate)):
                if senate[i] == 'R':
                    Radiant = True # 己方有人
                    if people < 0: # 被对方ban了
                        senate[i] = '0' # 下次检索不到了
                    people += 1
                if senate[i] == 'D':
                    Dire = True
                    if people>0:
                        senate[i] = '0'
                    people -= 1
        if people > 0 : return 'Radiant' # 判断存活方
        if people < 0 : return 'Dire'

402 移掉k位数字

输入num,移走k位数字,希望得到的数字最小,但返回的是字符串,且不可以有0。贪心算法,从左往右,遇到小的就把大的去掉,形成递增序列,肯定是前面小则整体小。

class Solution:
    def removeKdigits(self, num: str, k: int) -> str:
        res = []
        for ele in num:
            while k and res and res[-1]>ele:
                res.pop()
                k -= 1
            res.append(ele)
        res = res[:-k] if k else res # res递增,还剩下k个没删除,则从后面开始删
        return ''.join(res).lstrip('0') or '0' # 空字符串用‘0’代替

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值