LeetcodeDay16 区间问题

1 篇文章 0 订阅
1 篇文章 0 订阅

首先, 最重要的, 学会如何给区间排序

intervals.sort(key=lambda x:x[0])

56 合并区间

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        intervals.sort(key=lambda x:x[0])
        res = []
        for interval in intervals:
            if len(res) == 0:
                res.append(interval)
                continue
            a2, b2 = interval
            a1, b1 = res[-1]
            if a2 > b1:
                res.append(interval)
            else:
                res[-1] = [a1, max(b1, b2)]
        return res

很简单, 根据左侧排序后进行模拟就行

435 无重叠区间

给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠
输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort(key = lambda x:x[0])
        res = []
        count = 0
        for interval in intervals:
            a2, b2 = interval
            if len(res) == 0:
                res.append(interval)
                continue
            a1, b1 = res[-1]
            if a2 >= b1:
                res.append(interval)
            else:
                if b1 > b2:
                    res[-1] = interval
                count += 1
        return count

只能说和上一道题一模一样, 但是我们可以用贪心的算法, 每当有重叠时, 舍弃那个右端更大的

57 插入区间

原本一堆区间, 现加一个, 合并.
当然我们可以加了, 排序, 合并, 就和56一样了, 当然复杂了
思路很简单:

  1. 如果完全在cur左侧, 直接加res
  2. 如果有交集, 更新cur
  3. 如果完全在cur右侧, 先加入cur, 把剩下的加了
class Solution:
    def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
        res = []

        current_span = newInterval[:]
        for i in range(len(intervals)):
            print(current_span)
            a2, b2 = intervals[i]
            if b2 < current_span[0]:
                res.append(intervals[i])
                continue
            if  a2 > current_span[1]:
                res.append(current_span)
                res.extend(intervals[i:])
                break
            current_span = [min(a2, current_span[0]), max(b2, current_span[1])]
        if current_span not in res:
            res.append(current_span)
        return res

我一开始是没有最后的那个判断的, 实际上很重要, 因为可能存在一个情况s.t. cur一直都没被加进去

class Solution:
    def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
        left, right = newInterval
        placed = False
        ans = list()
        for li, ri in intervals:
            if li > right:
                # 在插入区间的右侧且无交集
                if not placed:
                    ans.append([left, right])
                    placed = True
                ans.append([li, ri])
            elif ri < left:
                # 在插入区间的左侧且无交集
                ans.append([li, ri])
            else:
                # 与插入区间有交集,计算它们的并集
                left = min(left, li)
                right = max(right, ri)
        
        if not placed:
            ans.append([left, right])
        return ans

官方题解就显得简洁多了, 用一个变量记录cur是否已经被加入进去

452 最少的箭去射爆气球

输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]

其实就是合并区间, 但是是合并成更小的

class Solution:
    def findMinArrowShots(self, points: List[List[int]]) -> int:
        points.sort(key = lambda x:x[0])
        res = []
        for a2, b2 in points:
            if len(res) == 0:
                res.append([a2, b2])
            else:
                a1, b1 = res[-1]
                if a2 > b1:
                    res.append([a2, b2])
                else:
                    res[-1] = [a2, min(b1, b2)]
        return len(res)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值