leetcode刷题之贪心算法

455.分发饼干
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

class Solution(object):
    def findContentChildren(self, g, s):
        gi = 0
        si = 0
        g.sort()
        s.sort()
        while gi < len(g) and si < len(s):
            if s[si] >= g[gi]:
                gi += 1
            si += 1
        return gi

435.无重叠区间
给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。

class Solution(object):
    def eraseOverlapIntervals(self, intervals):
         # 对intervals列表按照每个子列表的第一个元素进行排序
        intervals.sort(key=lambda x: x[0])
        result = 0

        # 遍历每一个子列表
        for i in range(1,len(intervals)):
            pre = intervals[i-1]
            cur = intervals[i]
            # cur左端点的值大于pre右端点的值 则证明不重合
            if cur[0] < pre[1]:
                result += 1
                # 
                intervals[i][1] = min(intervals[i-1][1], intervals[i][1])
        return result
        # 视频解析
        # https://www.bilibili.com/video/BV1A14y1c7E1/?spm_id_from=333.337.search-card.all.click&vd_source=5333ba15b46a8415fced47b74162923f

452. 用最少数量的箭引爆气球
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。

class Solution(object):
    def findMinArrowShots(self, points):
        points.sort(key = lambda x:x[0])
        result = 0
        for i in range (1, len(points)):
            pre = points[i-1]
            cur = points[i]
            if cur[0] <= pre[1]: # 如果区间重合 result就+1
                result += 1
                points[i][1] = min(points[i-1][1],points[i][1])
        l = len(points )
        return l - result
      

406. 根据身高重建队列

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

class Solution(object):
    def reconstructQueue(self, people):
        # 对于两个维度要考虑 首先考虑其中一个维度
        # -x[0] 表示对第一个值取负值,即进行降序排序。
        # 正数的负值是其相反数,负数的负值是其本身,因此对第一个值取负值后,会按照第一个值进行降序排序。
        people.sort(key = lambda x:(-x[0], x[1]))
        # x[1] 表示对第二个值进行升序排序
        res = []
        for p in people:
            # 获取位置 p[1]
            if len(res) <= p[1]: #
                # append 用于向列表的末尾添加一个元素
                res.append(p) # 添加到队尾的位置
            elif len(res) > p[1]:
                # insert在指定位置插入一个元素
                res.insert(p[1], p) 
        return res

121. 买卖股票的最佳时机
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

class Solution(object):
    def maxProfit(self, prices):
        cost, profit = float('+inf'), 0
        for price in prices:
            cost = min(cost, price) # 找最小的花费
            profit = max(profit, price - cost)  # 利润
        return profit

122. 买卖股票的最佳时机 II
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。

class Solution(object):
    def maxProfit(self, prices):
        profit = 0 #总利润
        tmp = 0 # 暂时利润
        for i in range(1, len(prices)):
            tmp = prices[i] - prices[i-1]
            # 股票连续上升可以分解为每天都上升
            if tmp > 0:
                profit += tmp
        return profit

605. 种花问题
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false 。

class Solution(object):
    def canPlaceFlowers(self, flowerbed, n):
        # 若当前地的前面和后面都为0,则该地可以种花
        # 考虑边界问题 最前面和最后面赋值为0
        count = 0
        flowerbed.insert(0,0)
        flowerbed.append(0)
        for i in range(1,len(flowerbed)-1):
            if flowerbed[i]==0 and flowerbed[i-1]==0 and flowerbed[i+1]==0:
                flowerbed[i] = 1 # 要先标记此处种花
                i += 2 #该位置可以种花 则下个位置肯定不能种花 直接跳到下下个位置进行判断
                count += 1
                
            else:
                i += 1
        return count>=n

392. 判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

class Solution(object):
    def isSubsequence(self, s, t):
        i = j = 0
        slen = len(s)
        tlen = len(t)
        while i < slen and j < tlen:
            if s[i] == t[j]:
                i += 1    
            j += 1
        return i == slen

655.非递减数列
给你一个长度为 n 的整数数组 nums ,请你判断在 最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列。

class Solution(object):
    def checkPossibility(self, num):
        N = len(num)
        count = 0
        for i in range(1, N):
           if num[i-1] > num[i]:
               count += 1
               # num[i-2] > num[i] 这种情况需要 num[i] = num[i-1]
               # 相反的话 num[i-2] <= num[i] 就num[i-1] = num[i]
               if i==1 or num[i-2] <= num[i]:
                   num[i-1] = num[i]
               else:
                   # 尽量改前面那个值 因为不知道后面的元素是什么
                    num[i] = num[i-1]
        return count <= 1          

53. 最大子数组和
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组
是数组中的一个连续部分。

# 用动态规划的思路做 暂时没太懂
class Solution(object):
    def maxSubArray(self, nums):
        
        size = len(nums)
        pre = 0
        ans = nums[0]
        for i in range(size):
            pre = max(nums[i], pre + nums[i])
            ans = max (ans, pre)
        return ans
        

下面是贪心算法的版本

class Solution(object):
    def maxSubArray(self, nums):
        # 贪心算法
        # 如果连续和A为负数 继续相加则只会让A+num[i]变小
        # 不如将连续和的七点变为num[i]
        size = len(nums)
        ans = 0
        lianxuhe = 0
        for i in range(size):
            lianxuhe += nums[i]
            # 如果连续和小于0 就将下一个数作为新的起点进行累加
            if lianxuhe > 0:
                ans =max(lianxuhe, ans)
            else:
                lianxuhe = 0
        return ans
  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何具体存储。例如,数组的连续存储,链表的动态分配节点,树和图的邻接矩阵或邻接表表示等。 基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、删除、查找、更新、遍历等,并分析这些操作的时间复杂度和空间复杂度。 算法算法设计:研究如何将解决问题的步骤形式化为一系列指令,使得计算机可以执行以求解问题。 算法特性:包括输入、输出、有穷性、确定性和可行性。即一个有效的算法必须能在有限步骤内结束,并且对于给定的输入产生唯一的确定输出。 算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法,分支限界法等。 算法分析:通过数学方法分析算法的时间复杂度(运行时间随数据规模增长的速度)和空间复杂度(所需内存大小)来评估其效率。 学习算法与数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值