将递归转化为分而治之
Translating recursion to divide and conquer
我正在尝试 return 列表中的三个最小项。下面是我写的 O(n) 解决方案:
def three_smallest(L):
# base case
if (len(L) == 3):
return sorted(L)
current = L[0]
(first_smallest,second_smallest,third_smallest) = three_smallest(L[1:])
if (current < first_smallest):
return (current, first_smallest, second_smallest)
elif (current < second_smallest):
return (first_smallest, current, second_smallest)
elif (current < third_smallest):
return (first_smallest, second_smallest, current)
else:
return (first_smallest,second_smallest,third_smallest)
现在我正在尝试编写一种分而治之的方法,但我不确定应该如何划分列表。任何帮助将不胜感激。
请注意,此解决方案(根据我的理解)不是分而治之。这只是一个基本的递归解决方案,因为分而治之涉及将长度为 n 的列表除以整数 b,并在这些部分上调用算法。
对于分而治之,您通常希望将一组(大致)分成两半,而不是一个一个地削减它。或许以下内容能满足您的需求?
def three_smallest(L):
if (len(L) <= 3): # base case, technically up to 3 (can be fewer)
return sorted(L)
mid = len(L) // 2 # find the midpoint of L
# find (up to) the 3 smallest in first half, ditto for the second half, pool
# them to a list with no more than 6 items, sort, and return the 3 smallest
return sorted(three_smallest(L[:mid]) + three_smallest(L[mid:]))[:3]
请注意,由于基本情况的不平等,此实现没有最小列表大小要求。
在天平的另一端,您的原始实现仅限于具有少于一千个值的列表,否则它会耗尽递归堆栈。上面给出的实现能够毫无问题地处理一百万个值的列表。
我正在尝试 return 列表中的三个最小项。下面是我写的 O(n) 解决方案:
def three_smallest(L):
# base case
if (len(L) == 3):
return sorted(L)
current = L[0]
(first_smallest,second_smallest,third_smallest) = three_smallest(L[1:])
if (current < first_smallest):
return (current, first_smallest, second_smallest)
elif (current < second_smallest):
return (first_smallest, current, second_smallest)
elif (current < third_smallest):
return (first_smallest, second_smallest, current)
else:
return (first_smallest,second_smallest,third_smallest)
现在我正在尝试编写一种分而治之的方法,但我不确定应该如何划分列表。任何帮助将不胜感激。
请注意,此解决方案(根据我的理解)不是分而治之。这只是一个基本的递归解决方案,因为分而治之涉及将长度为 n 的列表除以整数 b,并在这些部分上调用算法。
对于分而治之,您通常希望将一组(大致)分成两半,而不是一个一个地削减它。或许以下内容能满足您的需求?
def three_smallest(L):
if (len(L) <= 3): # base case, technically up to 3 (can be fewer)
return sorted(L)
mid = len(L) // 2 # find the midpoint of L
# find (up to) the 3 smallest in first half, ditto for the second half, pool
# them to a list with no more than 6 items, sort, and return the 3 smallest
return sorted(three_smallest(L[:mid]) + three_smallest(L[mid:]))[:3]
请注意,由于基本情况的不平等,此实现没有最小列表大小要求。
在天平的另一端,您的原始实现仅限于具有少于一千个值的列表,否则它会耗尽递归堆栈。上面给出的实现能够毫无问题地处理一百万个值的列表。