贪心力扣题解

此博主要是看了这篇的总结:https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode 题解 - 贪心思想.md

455. Assign Cookies分配饼干

  • 描述:每个孩子都有一个满足度,每个饼干都有一个大小,只有饼干的大小大于等于一个孩子的满足度,该孩子才会获得满足。求解最多可以获得满足的孩子数量。
  • 实例:
    Input: [1,2,3], [1,1]
    output=1
    Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3.
    And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content.
    You need to output 1.
  • 思路:尽可能的将小饼干给满意度小的学生
class Solution(object):
    def findContentChildren(self, g, s):
        g.sort()
        s.sort()
        i, j = 0, 0
        res = 0
        while i < len(g) and j < len(s):
            if s[j] >= g[i]:
                res+=1
                i+=1
            j+=1
        return res

435. Non-overlapping Intervals 重叠区间个数

  • 描述:计算让一组区间不重叠所需要移除的最少的区间个数。
  • 实例:
    Input: [ [1,2], [2,3], [3,4], [1,3] ]
    Output: 1
    Explanation: [1,3] can be removed and the rest of intervals are non-overlapping.
  • 思路:按照区间右端点的大小升序排序,这里升序排序的主要原因为给剩下的区间尽可能多的留下空间
class Solution(object):
    def eraseOverlapIntervals(self, intervals):
        """
        :type intervals: List[List[int]]
        :rtype: int
        """
        if len(intervals)<2:
            return 0
        count = 0
        intervals.sort(key=lambda x:x[1])
        i,j = 0,1
        while j < len(intervals):
            if intervals[i][1] > intervals[j][0]:
                count+=1
            else:
                i = j
            j+=1
        return count

452. Minimum Number of Arrows to Burst Balloons 投飞镖刺气球

  • 描述:气球在一个水平数轴上摆放,可以重叠,飞镖垂直投向坐标轴,使得路径上的气球都被刺破。求解最小的投飞镖次数使所有气球都被刺破。
  • 实例:
    Input: [[10,16], [2,8], [1,6], [7,12]]
    Output: 2
    Explanation:
    One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).
  • 思路:与上题做法类似,这题要求的是不重叠区间的个数
class Solution(object):
    def findMinArrowShots(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        if len(points)<1:
            return 0
        points.sort(key = lambda x:x[1])
        count = 0
        i,j=0,1
        while j<len(points):
            if points[i][1] >= points[j][0]:
                count+=1
            else:
                i=j
            j+=1
        return len(points)-count       

406. Queue Reconstruction by Height根据身高和序号排序

  • 描述:一个学生用两个分量 (h, k) 描述,h 表示身高,k 表示排在前面的有 k 个学生的身高比他高或者和他一样高。
  • 实例:Input: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
    Output: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
  • 思路:先按照身高降序排列,同身高的按照序号升序排列,然后将得到的数组按照序号的大小插入到另一个列表的对应位置上,就能得到最后的结果,原理就是按照身高降序排列是为了再后来插入时不影响插入到前面的元素的序号
    def reconstructQueue(self, people):
        """
        :type people: List[List[int]]
        :rtype: List[List[int]]
        """
        if len(people) < 2:
            return people
        people.sort(key=lambda p:[-p[0], p[1]])
        res = []
        for i in people:
            res.insert(i[1], i)
        return res

121. Best Time to Buy and Sell Stock买卖股票的最佳时间

  • 描述:一次股票交易包含买入和卖出,只进行一次交易,求最大收益。
  • 实例:
    Input: [7,1,5,3,6,4]
    Output: 5
    Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
    Not 7-1 = 6, as selling price needs to be larger than buying price
  • 思路:将当前价格作为卖出价格的话,找出之前的最小价格,记录最大值
class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices:
            return 0
        profit = [0]*len(prices)
        minimum = [0]*len(prices)
        profit[0] = 0
        minimum[0] = prices[0]
        for i in range(1,len(prices)):
            profit[i] = prices[i] - minimum[i-1]
            minimum[i] = prices[i] if prices[i]<minimum[i-1] else minimum[i-1]
            if profit[i] < profit[i-1]:
                profit[i] = profit[i-1]
        return profit[-1]

122. Best Time to Buy and Sell Stock II最大收益2

  • 描述:可以进行多次交易,多次交易之间不能交叉进行,可以进行多次交易。
  • 实例:
    Input: [7,1,5,3,6,4]
    Output: 7
    Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
    Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
  • 思路:最大收益问题,不限制次数,那么应该尽可能的在不交叉的情况下将可能的收益添加进去,倘若前者大于后者,就将收益添加进去
class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        res = 0
        for i in range(len(prices)-1):
            if prices[i+1]>prices[i]:
                res+=prices[i+1]-prices[i]
        return res        

605. Can Place Flowers种植花草

  • 描述:flowerbed 数组中 1 表示已经种下了花朵。花朵之间至少需要一个单位的间隔,求解是否能种下 n 朵花。
  • 实例:
    Input: flowerbed = [1,0,0,0,1], n = 1
    Output: True
  • 思路:每一个i按个中一朵花,尽可能多的种花,主要难点在于边界的检验。设置两个标志,表示当前遍历的位置的前后,如果前后均没种树,则当前位置可以种
class Solution(object):
    def canPlaceFlowers(self, flowerbed, n):
        """
        :type flowerbed: List[int]
        :type n: int
        :rtype: bool
        """
        count = 0
        for i in range(len(flowerbed)):
            if flowerbed[i] == 1:
                continue
            pre = 0 if i == 0 else flowerbed[i-1]
            next = 0 if i == len(flowerbed)-1 else flowerbed[i+1]
            if pre == 0 and next == 0:
                count+=1
                flowerbed[i] = 1
        return count>=n

392. Is Subsequence是否为子序列

  • 描述:判断一个字符串是否为另一个串的子串,要求字符顺序一样
  • 实例:
    s = “abc”, t = “ahbgdc”
    Return true.
  • 思路:遍历母串,如果字串字符都在木串中,即为子序列
class Solution(object):
    def isSubsequence(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if len(s)>len(t):
            return False
        i,j = 0,0
        while i<len(s) and j<len(t):
            if s[i] == t[j]:
                i+=1
            j+=1
        if i == len(s):
            return True
        else:
            return False         

665. Non-decreasing Array修改一个数,称为非递减数列

  • 描述:修改数组中的一个数就可以将该数组编程非递减的数列
  • 实例:
    Input: [4,2,3]
    Output: True
    Explanation: You could modify the first 4 to 1 to get a non-decreasing array.
  • 思路:如果前一个元素不大于后面的元素,则无需更改,否则,要更改一个元素,更改谁呢?因为前面已经遍历的元素都是满足非递减的,所以再往前数一个元素比较即可
class Solution(object):
    def checkPossibility(self, nums):

        if len(nums)<2:
            return True
        count = 0
        i = 1
        while i<len(nums) and count<2:
            if nums[i-1] <= nums[i]:
                i+=1
                continue
            count+=1
            if i-2>=0 and nums[i-2]>=nums[i]:
                nums[i] = nums[i-1]
            elif i-2>=0 and nums[i-2] < nums[i]:
                nums[i-1] = nums[i]
            i+=1
        return count<2       

53. Maximum Subarray最大子序列

  • 描述:求一个数组中的和最大的序列
  • 实例:
    Input: [-2,1,-3,4,-1,2,1,-5,4],
    Output: 6
    Explanation: [4,-1,2,1] has the largest sum = 6.
  • 思路:遍历元素,并记录当前及以前的元素之和,如果和为负了,相当于在当前元素的基础上还小,更新当前的和,否则,继续加
class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums)<1 or nums is None:
            return 
        presum = nums[0]
        maxsum = presum
        for i in range(1,len(nums)):
            presum = presum+nums[i] if presum>0 else nums[i]
            maxsum = max(maxsum,presum)
        return maxsum

763. Partition Labels 字符串分割

  • 描述:将字符串分割成最多的字串,要求任意字符只能在一个字符串中出现
  • 实例:
    Input: S = “ababcbacadefegdehijhklij”
    Output: [9,7,8]
    Explanation:
    The partition is “ababcbaca”, “defegde”, “hijhklij”.
    This is a partition so that each letter appears in at most one part.
    A partition like “ababcbacadefegde”, “hijhklij” is incorrect, because it splits S into less parts.
  • 思路:从第一个字符开始,找到它最大出现的地方,如果当前的位置与最大的索引位置相同,则分割
class Solution(object):
    def partitionLabels(self, S):
        """
        :type S: str
        :rtype: List[int]
        """
        res = []
        max_index = {}
        for k,v in enumerate(S):
            max_index[v] = k
        start,end = 0,0
        for k,v in enumerate(S):
            if end<max_index[v]:
                end = max_index[v]
            if k == end:
                res.append(end-start+1)
                start = end+1
        return res  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值