美文网首页
986. 区间列表的交集(Python)

986. 区间列表的交集(Python)

作者: 玖月晴 | 来源:发表于2021-05-08 11:17 被阅读0次

    难度:★★★☆☆
    类型:数组
    方法:逻辑

    题目

    力扣链接请移步本题传送门
    更多力扣中等题的解决方案请移步力扣中等题目录

    给定两个由一些 闭区间 组成的列表,firstList 和 secondList ,其中 firstList[i] = [starti, endi] 而 secondList[j] = [startj, endj] 。每个区间列表都是成对 不相交 的,并且 已经排序 。

    返回这 两个区间列表的交集 。

    形式上,闭区间 [a, b](其中 a <= b)表示实数 x 的集合,而 a <= x <= b 。

    两个闭区间的 交集 是一组实数,要么为空集,要么为闭区间。例如,[1, 3] 和 [2, 4] 的交集为 [2, 3] 。

    示例 1:

    输入:firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]]
    输出:[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]

    示例 2:

    输入:firstList = [[1,3],[5,9]], secondList = []
    输出:[]

    示例 3:

    输入:firstList = [], secondList = [[4,8],[10,12]]
    输出:[]

    示例 4:

    输入:firstList = [[1,7]], secondList = [[3,10]]
    输出:[[3,7]]

    提示:

    0 <= firstList.length, secondList.length <= 1000
    firstList.length + secondList.length >= 1
    0 <= starti < endi <= 109
    endi < starti+1
    0 <= startj < endj <= 109
    endj < startj+1

    解答

    我们当然可以用很笨的办法,将所有情况分类后讨论:

    class Solution:
        def intervalIntersection(self, firstList, secondList):
    
            res = []
            while firstList and secondList:
    
                if firstList[0][1] == secondList[0][0]:
                    res.append([secondList[0][0], firstList[0][1]])
                    firstList.pop(0)
    
                elif secondList[0][1] == firstList[0][0]:
                    res.append([firstList[0][0], secondList[0][1]])
                    secondList.pop(0)
    
                elif firstList[0][1] < secondList[0][0]:
                    firstList.pop(0)
    
                elif secondList[0][1] < firstList[0][0]:
                    secondList.pop(0)
    
                elif secondList[0][0] <= firstList[0][0] < secondList[0][1]:
                    if firstList[0][1] <= secondList[0][1]:
                        res.append(firstList.pop(0))
                    else:
                        res.append([firstList[0][0], secondList.pop(0)[1]])
    
                elif firstList[0][0] <= secondList[0][0] < firstList[0][1]:
                    if secondList[0][1] <= firstList[0][1]:
                        res.append(secondList.pop(0))
                    else:
                        res.append([secondList[0][0], firstList.pop(0)[1]])
    
            return res
    

    但是实际上,我们可以将以上各种情况做合并。

    将来自列表A和列表B的区间两两比较,我们只关心两个区间是否相交,以及公共区间在哪,因此只需要拿捏两个端点low,high,根据两者之间的大小,确定是否将结果更新。

    每次遍历结束后,弹出后续不会再被使用的区间。是否会再使用,取决于右端点。

    class Solution:
        def intervalIntersection(self, A, B):
            ans = []
    
            while A and B:
    
                lo = max(A[0][0], B[0][0])
                hi = min(A[0][1], B[0][1])
                if lo <= hi:
                    ans.append([lo, hi])
    
                if A[0][1] < B[0][1]:
                    A.pop(0)
                else:
                    B.pop(0)
    
            return ans
    

    精简后:

    class Solution:
        def intervalIntersection(self, A, B):
            ans = []
            while A and B:
                low, high = max(A[0][0], B[0][0]), min(A[0][1], B[0][1])
                ans += [[low, high]] if low <= high else []
                A.pop(0) if A[0][1] < B[0][1] else B.pop(0)
            return ans
    

    如有疑问或建议,欢迎评论区留言~

    有关更多力扣中等题的python解决方案,请移步力扣中等题解析

    相关文章

      网友评论

          本文标题:986. 区间列表的交集(Python)

          本文链接:https://www.haomeiwen.com/subject/lgczcltx.html