【发布时间】:2020-07-10 20:16:42
【问题描述】:
任何人都可以准确解释幕后发生的事情,以使以下问题中的递归方法在时间复杂度方面更快更有效吗?
问题:编写一个程序,将整数数组作为输入,并返回在数组中排序的最大三个数字,而不对原始(输入)数组进行排序。
例如:
-
输入:
[22, 5, 3, 1, 8, 2] -
输出:
[5, 8, 22]
尽管我们可以简单地对原始数组进行排序并返回最后三个元素,但这至少需要O(nlog(n)) 时间,因为最快的排序算法可以做到这一点。所以挑战是更好地执行并在O(n)时间完成任务。
所以我能够想出一个递归解决方案:
def findThreeLargestNumbers(array, largest=[]):
if len(largest) == 3:
return largest
max = array[0]
for i in array:
if i > max:
max = i
array.remove(max)
largest.insert(0, max)
return findThreeLargestNumbers(array, largest)
我一直在其中找到最大的数字,将其从原始数组中删除,将其附加到我的空数组中,然后再次递归调用该函数,直到我的数组中有三个元素。
但是,当我查看建议的迭代方法时,我编写了以下代码:
def findThreeLargestNumbers(array):
sortedLargest = [None, None, None]
for num in array:
check(num, sortedLargest)
return sortedLargest
def check(num, sortedLargest):
for i in reversed(range(len(sortedLargest))):
if sortedLargest[i] is None:
sortedLargest[i] = num
return
if num > sortedLargest[i]:
shift(sortedLargest, i, num)
return
def shift(array, idx, element):
if idx == 0:
array[0] = element
return array
array[0] = array[1]
array[idx-1] = array[idx]
array[idx] = element
return array
两个代码都成功通过了所有测试,我确信迭代方法更快(尽管不是那么干净......)。但是,我导入了时间模块并通过提供一百万个随机整数的数组并计算每个解决方案返回最大三个数字的排序数组需要多长时间来测试代码。
递归方法比迭代方法快得多(大约快 9 倍)!
这是为什么呢?即使递归方法遍历巨大的数组 3 次,除此之外,每次它删除一个元素(这需要 O(n) 时间,因为所有其他 999 元素都需要在内存中移动),而迭代方法是只遍历输入数组一次,是的,在每次迭代时都进行一些操作,但是使用一个非常微不足道的大小为 3 的数组,甚至根本不需要时间!
我真的希望能够针对任何给定问题判断和选择最有效的算法,因此任何解释都会有很大帮助。
【问题讨论】:
标签: python arrays algorithm data-structures