算法之贪心算法(一)

本文解析了贪心算法在解决实际问题中的应用,如如何利用贪心策略在股票买卖中寻找最大利润,以及如何合并重叠区间以简化表示。通过实例讲解,深入浅出地展示了如何在买卖股票问题(LeetCode 122)和合并区间问题(LeetCode 56)中采用贪心策略求解。
摘要由CSDN通过智能技术生成

贪心算法(Greedy)

贪心法,在对问题求解的时候总是做出当前看来是最好的选择。由此它没有状态转移,所以大部分情况下看成是一维问题。整体使用次数不多,但是简单易于理解。

贪心算法场景

能够分成子问题来解决,并且子问题最优解能递推到全局最优解,这种子问题成为最优子结构。

贪心算法对子问题作出最优选择后,不能回退,一直往下递推。假如每次选择都进行记录,并且记录多种选择状态,根据以前的结果来进行多种选择状态下的最优解,就是动态规划。

贪心的实战

1. 买卖股票问题

leetcode122

给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。

在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。
返回 你能获得的 最大 利润 。

示例 1:

输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
示例 2:

输入: prices = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:

输入: prices = [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
      max_profile=0
      for i in range(1,len(prices)):
        if prices[i] >prices[i-1]:
          max_profile +=prices[i]-prices[i-1]
      return max_profile   

2. 合并区间

leetcode 56

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-intervals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

  1. 子问题为list [i-1] [1] >=list [i] [0] >=list [i-1] [0] ,后一个list的start 位于前一个list中的start end 之间。
  2. 只要上面成立list [i-1] [1] 与 list[i] [1] 有end的选项 ,将end 取两个list 中end的较大值
  3. append 进入结果项
class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        intervals_size=len(intervals)
        if not intervals_size:
            return []
        intervals.sort()
        start=intervals[0][0]
        end= intervals[0][1]
        res=[]
        for i in range(1,intervals_size):
            if intervals[i][0] >= start and intervals[i][0]<=end:
                end= max(intervals[i][1],end)
            else:
                res.append([start,end])
                start=intervals[i][0]
                end =intervals[i][1]
        res.append([start,end]) 
        return res
class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:

        if not intervals:
            return []
        intervals.sort()
        res=[]
        for i in intervals:
            if not res or res[-1][1]<i[0]:
                res.append(i)
            else:
                res[-1][1]=max(i[1],res[-1][1])
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值