题目:
单个线段[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
本文来自程序媛驿站,未经授权不得转载.
如有需要请公众号后台联系
(欢迎转发到朋友圈~)