Leetcode每日刷题【中】--Day 8

435. 无重叠区间(贪心)

贪心策略是:尽可能让选入的区间的右边界小,因为这样才能纳入更多的区间,相应的不需要删去太多区间。这就达到了减去最小区间数而使得区间不重叠。

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort(key=lambda x: x[1])  # 根据右边界排序
        ans = [intervals[0]]   #先纳入第一个区间  这样的写法稍微复杂一些。可以简略点
        a = 0  # 用来遍历ans的下标
        num = 0  # 记录删去的数目
        
        for i in intervals[1:]:  # 从第二个开始遍历
            if i[0] < ans[a][1]:  # 如果该区间左边界小于上一个选定区间的右边界,就进行“删除”,删除数一
                num += 1
            else:
                ans.append(i)  # 满足条件就纳入
                a += 1  # 准备下一次使用
                
        return num
605. 种花问题(贪心)

代码写得很丑,思路比较简单。

class Solution:
    def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
        lenth = len(flowerbed)  # 计算种花区间
        num = 0  # 最终的答案
        for i in range(lenth):
            if flowerbed[i] == 0:  # 如果当前有位置
            
            	# 第一种情况:并且当前位置处于开头,在空间足够大的情况下,判断相邻是否有花
                if i == 0 and lenth >= 2 and flowerbed[i+1] == 0:  
                    flowerbed[i] = 1   # 可以种花就种
                    num += 1  # 数量加一
                if i >= 1 and i < lenth - 1:  # 第二种情况,在中间位置
                    if flowerbed[i-1] == 0 and flowerbed[i+1] == 0:  # 左右无花
                        flowerbed[i] = 1  # 种!
                        num += 1
                if i == lenth - 1 and flowerbed[i-1] == 0:  # 最后位置,相邻的左边无花
                    flowerbed[i] = 1  # 种!
                    num += 1
        
        return num >= n  # 返回bool

题解思路:

一个公式:能种花位置数 P 与最多花的数量M关系是: (P + 1)/ 2

  • 在 下标ij 种了花,且[i+1, j-1]之间没有花。

  • 那么只有当 j-i>=4 时才可以在下标 i 和 j 之间种花

  • 可种花下标 [i+2, j-2]

  • 能种花的位置数是 p = j-i-3 (理解为-1-2 1是左边i的那个位置,2是左右都要空一个位置才能种)

  • p为奇数 最多可种(p+1)/2

  • p为偶数 最多可种 p/2 因为整数除法规则 两者相等

  • 所以 能种 (j-i-2)/2

  • 如果 l 的左边没有种花,r 的右边没有种花,记为空格下标 k

  • flowerbed[ k ] = 0

  • (将下标 l 理解为下标 l 处左边还有多少个空地)如果 l < 2无法在左边种花(只有两个位置,必定相邻) ; l >= 2 可在(下标 l-2理解为当前的左边第二个为界限)[0, l-2] 范围种花,可以种植 l - 1(左边有l个位置,需要隔出一个),最多l / 2 朵花

  • 令 m为数组flowerbed 长度下标r右边有 m-r-1个位置,可种 m-r-2, 最多可种 (m-r-1)/2 朵花

  • 如果没有任何花 ,可种 (m+1)/2 朵

根据上述计算方法,计算最多可种的数量,加以判断>=n

class Solution:
    def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
        count, m, prev = 0, len(flowerbed), -1
        for i in range(m):
            if flowerbed[i] == 1:
                if prev < 0:  # 一开始第一次遇到花
                    count += i // 2  # 计算(i-1)为前段可种的位置数,(位置数+1)/2
                else:  # 之后遇到了花
                    # prev是上回花的位置, i是前面的位置
                    count += (i - prev - 2) // 2  # 理解:(位置数+1)/2    (i-prev-3+1)
                prev = i
        
        if prev < 0:  # 一直没遇到花  计算全盘能种多少花
            count += (m + 1) // 2  # 理解:(位置数+1)/2
        else:  # 遍历完之后再来一次  这种情况是最后一个没有花
            count += (m - prev - 1) // 2  # 理解:(位置数+1)/2       (m-prev-2+1)
        
        return count >= n

理解了半天终于懂了咳咳。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JamePrin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值