假设您有以下两个列表:
l1 = [0,30,45,55,80,90]
l2 = [35,65,70,75,100,120]
列表规则:
目标:
基本上每个数字都是打开和关闭某个东西的索引。目标是返回l2
中关闭l1
l2
项
解释
l1
中的项目将“关闭”l1
中距离最近的数字最近的项目。那么这两个数字都不再可用了。使用作为示例给出的列表,会发生这种情况:
0打开
30开启
35关闭30
45开启
55打开
65关闭55
70关闭45
75关闭0
answer = 75
我相信有一种方法可以做到这一点,只需遍历每个列表一次。我提出的方式,需要在事情结束时多次迭代def f(l1,l2):
for x in l2:
new_l = [i for i in l1 if i < x]
closed = new_l[-1]
if closed == 0:
answer = x
break
else:
l1.remove(closed)
return answer
。所以在这个例子中,它必须迭代4次才能得到正确的答案。这是函数:
{{1}}
有没有办法检测什么关闭什么,所以我不需要根据需要迭代多次。在我的实际情况中,这可能需要数百次迭代,因为这个函数实际上将在一个可能会持续一段时间的循环中运行
答案 0 :(得分:3)
您可以使用bisect
模块:
import bisect
def f(l1,l2):
for x in l2:
ind = bisect.bisect(l1,x)
# if the index where the item from l2 can fit in l1 is 1,
# then it's time to return
if ind - 1 == 0:
return x
del l1[ind-1] #otherwise remove the item from l1
l1 = [0,30,45,55,80,90]
l2 = [35,65,70,75,100,120]
print f(l1,l2)
#75
答案 1 :(得分:1)
此问题是标准括号匹配问题的变体。主要的区别在于,开启器和闭门器不是单一的开启器和闭合器序列,而是编号,它们的顺序由它们的数字来定义。我们可以懒洋洋地将它们合并为一个序列,然后完成序列并保持未闭合开启者的计数,直到我们找到第一个开启者的更接近。这在O(n)中运行,其中n是第一个开启者的近点的索引。
def merge_iterator(openers, closers):
"""Goes through the openers and closers, merging the sequences.
Yields (opener, 1) or (closer, -1) tuples, sorted by the values of the
openers or closers. Each yield runs in O(1).
"""
openers = iter(openers)
closers = iter(closers)
opener = next(openers)
closer = next(closers)
try:
while True:
if opener < closer:
yield opener, 1
opener = next(openers)
else:
yield closer, -1
closer = next(closers)
except StopIteration:
# Ran out of openers. (We can't run out of closers first.)
yield closer, -1
for closer in closers:
yield closer, -1
def find_closer(openers, closers):
merged_sequence = merge_iterator(openers, closers)
# open the first opener
unclosed = 1
next(merged_sequence)
# open and close openers until the first opener closes
for item, change_in_unclosed in merged_sequence:
unclosed += change_in_unclosed
if not unclosed:
# We closed the first opener. Return the closer.
return item
答案 2 :(得分:0)
这对你有用吗</ p>
def findBiggest(L, val):
""" Basically a modified binary search """
if len(L) == 1:
return L[0]
elif L[len(L)/2] >= val:
return biggest(L[:len(L)/2], val)
else:
return findBiggest(L[len(L)/2:], val)
def findOpens(opens, closes):
for c in closes:
opener = findBiggest(opens, c)
opens.remove(opener)
if opener == 0:
print 'answer =', c
return opener
答案 3 :(得分:0)
这应该是O(N)
中的诀窍。
def find_answer(l1, l2):
opened = 0
curr_l2 = 0
for el in l1:
if el > l2[curr_l2]:
while curr_l2 < len(l2) and el > l2[curr_l2]:
if opened == 1:
return l2[curr_l2]
elif opened > 1:
# l2[curr_l2] closes an element.
opened -= 1
curr_l2 += 1
else:
# Noone left to close
return None
# `el` opens
opened += 1
# Remaining elements to close left
return None