【贪心算法】leetcode刷题

这篇具有很好参考价值的文章主要介绍了【贪心算法】leetcode刷题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

贪心算法无固定套路。
核心思想:先找局部最优,再扩展到全局最优。

455.分发饼干

【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
两种思路:
1、从大到小。局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。先遍历的胃口,在遍历的饼干
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        g = sorted(g,reverse=True)
        s = sorted(s,reverse=True)
        count = 0
        si = 0
        for gi in g:
            if si<len(s) and s[si]>=gi:   # 饼干要大于胃的容量,才能喂饱
                count+=1
                si+=1             
        return count

2、从小到大。小饼干先喂饱小胃口。两个循环的顺序改变了,先遍历的饼干,在遍历的胃口,这是因为遍历顺序变了,我们是从小到大遍历。

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        g = sorted(g)
        s = sorted(s)
        count = 0
        gi = 0
        for si in s:
            if gi<len(g) and g[gi]<=si:  # 胃的容量要小于等于饼干大小才能喂饱
                count+=1
                gi+=1    
                
        return count

376. 摆动序列

【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
具体实例:
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。
**整体最优:**整个序列有最多的局部峰值,从而达到最长摆动序列。

考虑几种情况:

  • 情况一:上下坡中有平坡
  • 情况二:数组首尾两端
  • 情况三:单调坡中有平坡

情况一:上下坡中有平坡
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
它的摇摆序列长度是多少呢? 其实是长度是 3,也就是我们在删除的时候 要不删除左面的三个 2,要不就删除右边的三个 2。
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
在图中,当 i 指向第一个 2 的时候,prediff > 0 && curdiff = 0 ,当 i 指向最后一个 2 的时候 prediff = 0 && curdiff < 0。
如果我们采用,删左面三个 2 的规则,那么 当 prediff = 0 && curdiff < 0 也要记录一个峰值,因为他是把之前相同的元素都删掉留下的峰值。
所以我们记录峰值的条件应该是: (preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0),为什么这里允许 prediff == 0 ,就是为了 上面我说的这种情况。

情况二:数组首尾两端
例如序列[2,5],如果靠统计差值来计算峰值个数就需要考虑数组最左面和最右面的特殊情况。
因为我们在计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i])的时候,至少需要三个数字才能计算,而数组只有两个数字。
这里我们可以写死,就是 如果只有两个元素,且元素不同,那么结果为 2。
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法

情况三:单调坡度有平坡
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        count = 1
        # 情况二,小于等于2的情况,可以写死
        if len(nums)<2:
            return len(nums)
        if len(nums)==2:
            if nums[-1]-nums[0]==0:
                return 1
            return len(nums)
        # 情况一以及情况三:
        prediff = 0
        for i in range(0,len(nums)-1):
            # if i>0:
            #     prediff = nums[i-1]-nums[i]
            curdiff = nums[i]-nums[i+1]
            if (prediff<=0 and curdiff>0) or (prediff>=0 and curdiff<0):
                count+=1
                prediff = curdiff   # 更新prediff
        return count  

122.买卖股票的最佳时机 II

【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
如果想到其实最终利润是可以分解的,那么本题就很容易了!
如何分解呢?
假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。
相当于==(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])==。
此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑!
那么根据 prices 可以得到每天的利润序列:(prices[i] - prices[i - 1])…(prices[1] - prices[0])。

  • 局部最优:收集每天的正利润,全局最优:求得最大利润。
    【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [0]*(n-1)
        for i in range(1,n):
            dp[i-1] = prices[i]-prices[i-1]
        res = 0
        for i in dp:
            if i>0:
                res+=i
        return res

55. 跳跃游戏

【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
i 每次移动只能在 cover 的范围内移动,每移动一个元素,cover 得到该元素数值(新的覆盖范围)的补充,让 i 继续移动下去。
而 cover 每次只取 max(该元素数值补充后的范围, cover 本身范围)。
如果 cover 大于等于了终点下标,直接 return true 就可以了

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        n = len(nums)
        cover = 0
        if n<2:
            return True
        for i in range(n-1):
            if cover>=i:
                cover = max(cover,i+nums[i])
            if cover>=n-1:
                return True
        return False

45.跳跃游戏 II

【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
如果移动下标等于当前覆盖最大距离下标, 需要再走一步(即 ans++),因为最后一步一定是可以到的终点。(题目假设总是可以到达数组的最后一个位置),如图:
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
如果移动下标不等于当前覆盖最大距离下标,说明当前覆盖最远距离就可以直接达到终点了,不需要再走一步。如图:
【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法

class Solution:
    def jump(self, nums: List[int]) -> int:
		cur_distance = 0  # 当前覆盖的最远距离下标
        ans = 0  # 记录走的最大步数
        next_distance = 0  # 下一步覆盖的最远距离下标
        
        for i in range(len(nums) - 1):  # 注意这里是小于len(nums) - 1,这是关键所在
            next_distance = max(nums[i] + i, next_distance)  # 更新下一步覆盖的最远距离下标
            if i == cur_distance:  # 遇到当前覆盖的最远距离下标
                cur_distance = next_distance  # 更新当前覆盖的最远距离下标
                ans += 1
        
        return ans

1005.K次取反后最大化的数组和

【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法

class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        nums.sort(key=lambda x:abs(x),reverse=True)  # 按照绝对值的个数排序,且从大到小,为了后面先将前k个大负数进行翻转为正数,保证和最大
        for i in range(len(nums)):
            if nums[i]<0 and k>0:   # 将负数都翻转为正数
                k-=1
                nums[i] = -nums[i]
                
        # 现在全部都是正数了
        if k%2==1: # 如果还剩奇数个,则将最小的正数翻转
            nums[-1] = -nums[-1]

        # 如果是偶数,其实不用管,因为随便翻转个正数偶数次就可以了,不影响最后结果
        return sum(nums)

134. 加油站

135.分发糖果

【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法

  • 从左到右:
    如果ratings[i] > ratings[i - 1] 那么[i]的糖 一定要比[i - 1]的糖多一个,所以贪心:candyVec[i] = candyVec[i - 1] + 1
    【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法
  • 从右到左考虑:
    再确定左孩子大于右孩子的情况(从后向前遍历)
    遍历顺序这里有同学可能会有疑问,为什么不能从前向后遍历呢?
    因为 rating[5]与rating[4]的比较 要利用上 rating[5]与rating[6]的比较结果,所以 要从后向前遍历。
    如果从前向后遍历,rating[5]与rating[4]的比较 就不能用上 rating[5]与rating[6]的比较结果了 。如图:
    【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法

如果 ratings[i] > ratings[i + 1],此时candyVec[i](第i个小孩的糖果数量)就有两个选择了,一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。
那么又要贪心了,局部最优:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,保证第i个小孩的糖果数量既大于左边的也大于右边的。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。

所以就取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,candyVec[i]只有取最大的才能既保持对左边candyVec[i - 1]的糖果多,也比右边candyVec[i + 1]的糖果多。

class Solution:
    def candy(self, ratings: List[int]) -> int:
        k = len(ratings)
        dp = [1]*k
        # 从左到右
        for i in range(k):
            if i>0 and ratings[i]>ratings[i-1]:
                dp[i] = dp[i-1]+1
        # 从右到左
        for i in range(k-2,-1,-1):
            if ratings[i]>ratings[i+1]:
                dp[i] = max(dp[i+1]+1,dp[i])  # 关键点 见解析
        return sum(dp)

860. 柠檬水找零

【贪心算法】leetcode刷题,数据结构与算法,贪心算法,leetcode,算法文章来源地址https://www.toymoban.com/news/detail-625097.html

class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        if bills[0] != 5:
            return False
        n = len(bills)
        counter = {5: 0}
        for i in range(n):
            remain = bills[i]
            # 添加
            if remain in counter.keys():
                counter[remain] += 1
            else:
                counter[remain] = 1

            # 删除 # 若有20的,先找10元的。
            if remain // 10 > 1 and 10 in counter.keys():
                if counter[10] >= (remain // 10) - 1:  # 先找10元的。
                    counter[10] = counter[10] - ((remain // 10) - 1)
                    remain = ((remain // 10) - 1) * 10

            # 删除 若是10/20,则进行删除操作
            if remain // 5 > 1:
                if counter[5] >= (remain // 5) - 1:  # 再找5元的。剩余的5个数,大于需要找回的。
                    counter[5] = counter[5] - ((remain // 5) - 1)
                else:
                    return False
        return True

到了这里,关于【贪心算法】leetcode刷题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java数据结构与算法刷题-----LeetCode667. 优美的排列 II

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 题目要求我们返回一个数组长度为n的数组,必须含有1~n的所有数,并且从左到右,相邻的元素依次相减,它们的差,必

    2024年01月25日
    浏览(52)
  • java数据结构与算法刷题-----LeetCode240. 搜索二维矩阵 II

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 法一:把整个数组遍历一遍,时间复杂度O(m*n) 法二:每一行用二分搜索,那么时间复杂度就是O(m * l o g 2 n log_2{n} l o g

    2024年01月22日
    浏览(61)
  • java数据结构与算法刷题-----LeetCode209. 长度最小的子数组

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 代码:时间复杂度O(n).空间复杂度O(1)

    2024年01月21日
    浏览(54)
  • DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台、刷题集合、问题为导向的十大类刷题算法(数组和字符串、栈和队列、二叉树、堆实现、图、哈希表、排序和搜索、动态规划/回溯法/递归/贪心/分治)总

    Algorithm:【算法进阶之路】之算法面试刷题集合—数据结构知识和算法刷题及其平台、问题为导向的十大类刷题算法(数组和字符串、链表、栈和队列、二叉树、堆、图、哈希表、排序和搜索、回溯算法、枚举/递归/分治/动态规划/贪心算法)总结 目录 相关文章

    2024年02月08日
    浏览(56)
  • java数据结构与算法刷题-----LeetCode96. 不同的二叉搜索树

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 很多人觉得动态规划很难,但它就是固定套路而已。其实动态规划只不过是将多余的步骤,提前放到dp数组中(就是一个数组,只

    2024年01月21日
    浏览(56)
  • java数据结构与算法刷题-----LeetCode378. 有序矩阵中第 K 小的元素

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 已知矩阵相对有序,可以用二分搜索,不过和一维数组排序不同,这是二维的 每一行都递增,每一列也是递增,所以每

    2024年01月23日
    浏览(51)
  • java数据结构与算法刷题-----LeetCode1091. 二进制矩阵中的最短路径

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 双分裂蛇:是求二维表中从起点到终点的经典思路(也是求无权图的最短路径问题的经典解法)。创建两条分裂蛇,分别从起点和

    2024年04月26日
    浏览(52)
  • 数据结构与算法——贪心算法简介

    贪心算法是一种算法范式,它遵循在每个阶段做出局部最优选择的问题解决启发式,希望找到全局最优。换句话说,贪心算法在每一步都选择最好的选项,而不考虑该选择对未来步骤的影响。 当一个问题可以分解成更小的子问题,并且每个子问题的解决方案可以组合起来解决

    2023年04月08日
    浏览(37)
  • 数据结构与算法(3)——贪心算法

    定义:所谓“贪心”,就是每次只考虑自己附近局部范围的最优解,但这种局部最优会导致全局最优。 考虑当前的附近一两步即可 455. 分发饼干 简评:简单的贪心算法,将“胃口”和“饼干”按升序排列后,每次都只考虑“胃口”最小的小孩,然后把最小的饼干给他,如果

    2024年02月07日
    浏览(54)
  • 数据结构与算法之贪心&动态规划

            一:思考         1.某天早上公司领导找你解决一个问题,明天公司有N个同等级的会议需要使用同一个会议室,现在给你这个N个会议的开始和结束 时间,你怎么样安排才能使会议室最大利用?即安排最多场次的会议?电影的话 那肯定是最多加票价最高的,入场

    2024年02月09日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包