【编程题】【未知出处】数组段的完全覆盖

题目:

单个线段[2,6]可称为完全覆盖[4,6],现有两组线段,判断A组能否完全覆盖B组

例如:

    [[1, 3], [2, 6]] 

    [[1, 4], [4, 5]] 

    True

    [[1, 2], [4, 7]] 

    [[2, 5], [6, 7]]

    False

 

相关题目:【leetcode56:合并区间】

 

方法一:

合并数组段后逐个比较

方法:

建一个足够大的数组,线段区间在内就为1

一次遍历得到数组中为1的为覆盖情况

逐个单位进行比较,判断a是否能覆盖b

思想:只要B中存在的位置(为1)在A中不存在(为0),即为无法完全覆盖

复杂度:merge时先排序O(nlogn),然后合并O(n),比较O(n)。

def solution(a, b):
        a_array, a_start, a_end = merge(a) 
        b_array, b_start, b_end = merge(b)
        #  merge函数 建一个足够大的数组,线段区间在内就为1
        # 一次遍历得到数组中为1的为覆盖情况
        if b_start<a_start or b_end>a_end: return False
        # 逐个单位进行比较,判断a是否能覆盖b
        for i in range(b_start, b_end+1):
            if b_array[i-b_start]==1:
                if a_array[i-a_start]==0: return False
        return True
"""
    [[1, 3], [2, 6]] [1, 1, 1, 1, 1, 1]
    [[1, 4], [4, 5]] [1, 1, 1, 1, 1]
    True
    [[1, 2], [4, 7]] [1, 1, 0, 1, 1, 1, 1]
    [[2, 5], [6, 7]] [1, 1, 1, 1, 1, 1]
    False
    """
---------------------
作者:love_green
来源:CSDN
原文:https://blog.csdn.net/sinat_20280061/article/details/82182075
版权声明:本文为博主原创文章,转载请附上博文链接!

 

方法二:合并后二分查找

merge两个数组时,不使用1/0,直接存储merge后的数组段,具体方法为Leec56

判断B中一条是否被A覆盖的方法:对于一个b,(二分查找)找到A中的start小于b.s的线段a,判断a.end是否大于b.end

所以我们在排序完的数组基础上 维护一个右端点的前缀最大值

二分查找的终止条件:找到start小于等于他的最大下标

class Solution:
    def merge(self, intervals):
        result = []
        if not intervals:
            return result
        intervals.sort()
        for inter in intervals:
            if not result or inter[0] > result[-1][1]:
                result.append(inter)
            else:
                result[-1][1] = max(inter[1], result[-1][1])
        return result

    def a(self, s1, s2):
        def segment_cover(s, s1):
            l, r = 0, len(s1) - 1
            while l < r - 1:
                mid = (l + r) / 2 # 或 mid = (l + r) >> 1
                if s1[mid][0] == s[0]:
                    l = mid
                    break
                elif s1[mid][0] > s[0]:
                    r = mid
                else:
                    l = mid
            if s1[l][0] > s[0]:
                return False
            x = r if s1[r][0] <= s[0] else l
            return s1[x][1] >= s[1]

        s1 = self.merge(s1)
        s2 = self.merge(s2)
        if s2[0][0] < s1[0][0] or s2[-1][1] > s1[-1][1]:
            return False
        for segment in s2:
            if segment_cover(segment, s1) == False: return False
        return True

 

 

 

 

 

 

 

 

 

 

本文来自程序媛驿站,未经授权不得转载.

如有需要请公众号后台联系

(欢迎转发到朋友圈~)

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值