python里的各种范围_Python中两个范围列表的交集

A friend of mine passed me over an interview question he recently got and I wasn't very happy with my approach to the solution. The question is as follows:

You have two lists.

Each list will contain lists of length 2, which represent a range (ie. [3,5] means a range from 3 to 5, inclusive).

You need to return the intersection of all ranges between the sets. If I give you [1,5] and [0,2], the result would be [1,2].

Within each list, the ranges will always increase and never overlap (i.e. it will be [[0, 2], [5, 10] ... ] never [[0,2], [2,5] ... ])

In general there are no "gotchas" in terms of the ordering or overlapping of the lists.

Example:

a = [[0, 2], [5, 10], [13, 23], [24, 25]]

b = [[1, 5], [8, 12], [15, 18], [20, 24]]

Expected output:

[[1, 2], [5, 5], [8, 10], [15, 18], [20, 24]]

My lazy solution involved spreading the list of ranges into a list of integers then doing a set intersection, like this:

def get_intersection(x, y):

x_spread = [item for sublist in [list(range(l[0],l[1]+1)) for l in x] for item in sublist]

y_spread = [item for sublist in [list(range(l[0],l[1]+1)) for l in y] for item in sublist]

flat_intersect_list = list(set(x_spread).intersection(y_spread))

...

But I imagine there's a solution that's both readable and more efficient.

Please explain how you would mentally tackle this problem, if you don't mind. A time/space complexity analysis would also be helpful.

Thanks

解决方案

OP, I believe this solution works, and it runs in O(m+n) time where m and n are the lengths of the lists. (To be sure, make ranges a linked list so that changing its length runs in constant time.)

def intersections(a,b):

ranges = []

i = j = 0

while i < len(a) and j < len(b):

a_left, a_right = a[i]

b_left, b_right = b[j]

if a_right < b_right:

i += 1

else:

j += 1

if a_right >= b_left and b_right >= a_left:

end_pts = sorted([a_left, a_right, b_left, b_right])

middle = [end_pts[1], end_pts[2]]

ranges.append(middle)

ri = 0

while ri < len(ranges)-1:

if ranges[ri][1] == ranges[ri+1][0]:

ranges[ri:ri+2] = [[ranges[ri][0], ranges[ri+1][1]]]

ri += 1

return ranges

a = [[0,2], [5,10], [13,23], [24,25]]

b = [[1,5], [8,12], [15,18], [20,24]]

print(intersects(a,b))

# [[1, 2], [5, 5], [8, 10], [15, 18], [20, 24]]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值