自学内容网 自学内容网

Leetcode算法基础篇-贪心算法

简介

学习链接:贪心算法(第 10 ~ 12 天)

贪心算法(Greedy Algorithm):一种在每次决策时,总是采取在当前状态下的最好选择,从而希望导致结果是最好或最优的算法。

贪心问题的两个特征:

  • 贪心选择:问题的全局最优解可以通过一系列的局部最优解来得到
  • 最优子结构:问题的最优解包含其子问题的最优解

解题三步走:

  1. 转换问题:将原问题转换为贪心选择问题,先做出选择,再解决剩下的一个子问题
  2. 贪心选择策略:制定贪心策略,选取当前状态下最优解,得到局部最优解
  3. 最优子结构:根据贪心策略,将贪心选择局部最优解与子问题最优解合并得到全局最优解

练习题

455. 分发饼干

思路

  • 贪心策略:我们将小孩和饼干都按照从小到大的顺序排序,然后枚举每一块饼干,如果符合就给,不符合就下一块
  • 代码实现。

代码

class Solution(object):
    def findContentChildren(self, g, s):
        """
        :type g: List[int]
        :type s: List[int]
        :rtype: int
        """
        g, s = sorted(g), sorted(s)
        ans = 0
        i, j = 0, 0
        while i < len(g) and j < len(s):
            cookie = s[j]
            child = g[i]
            if cookie >= child:
                ans += 1
                j += 1
                i += 1
            else: 
                j += 1


        return ans

2410. 运动员和训练师的最大匹配数

思路

  • 和上一题一模一样

代码

class Solution(object):
    def matchPlayersAndTrainers(self, players, trainers):
        """
        :type players: List[int]
        :type trainers: List[int]
        :rtype: int
        """
        players = sorted(players)
        trainers = sorted(trainers)
        ans = 0
        i, j = 0, 0
        while i < len(players) and j < len(trainers):
            player, trainer = players[i], trainers[j]
            if player <= trainer:
                ans += 1
                i += 1
                j += 1
            else:
                j += 1
        return ans

435. 无重叠区间

思路

  • 贪心策略:我们将所有的区间按照右端点排序,这样可以确定最先结束的区间,从而能够给后续区间留下足够多的空间,使得区间数最多,记录一个当前右端点的位置 left 和重叠区间数 cnt
  • 遍历所有区间,每次比较区间的左端点和当前右端点 left,如果重叠,则记录一次,并更新 left
  • 最后所有区间数减去重叠区间数即为答案。

代码

class Solution(object):
    def eraseOverlapIntervals(self, intervals):
        """
        :type intervals: List[List[int]]
        :rtype: int
        """
        intervals.sort(key=lambda x: x[1])
        left = intervals[0][1]
        cnt = 1
        for i in range(1, len(intervals)):
            interval = intervals[i]
            if interval[0] >= left:
                cnt += 1
                left = interval[1]

        return len(intervals) - cnt

452. 用最少数量的箭引爆气球

思路

  • 和上题考点相同,直接统计重叠区间数即可。

代码

class Solution(object):
    def findMinArrowShots(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        points.sort(key=lambda x: x[1])
        n = len(points)
        left = points[0][1]
        cnt = 1
        for i in range(1, n):
            if points[i][0] > left:
                cnt += 1
                left = points[i][1]
        
        return cnt

原文地址:https://blog.csdn.net/qq_43471354/article/details/142453614

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!