最近我参加了一个Python编码挑战,我被要求查找列表的大小。
例如,如果列表为l = [100, 100, 100]
,则应返回3.
该列表被称为具有未知数量元素的虚拟列表。
提供了getElement()
函数,它将索引作为参数,并返回值100,假设列表的所有元素都是100。
def getElement(index):
###some exception logic for index out of range
return 100
因此我被要求编写一个函数def findListSize()
,该函数将返回列表的大小,条件是仅调用getElement()
函数。拨打getElement()
的次数越少,奖励积分就越多。
def findListSize():
array_size = 0
###logic here
return array_size
我无法朝着正确的方向前进来解决问题。有人能帮助我吗?
答案 0 :(得分:3)
如果你只能使用getElement
,那么天真的解决方案就是在循环中调用getElement
并增加索引,并计算它失败前的成功频率。但这可能会经常调用getElement
(对于列表中的每个元素一次)。
size = 0
try:
while True:
getElement(size)
size += 1
except:
print("size is", size)
或者,您可以先使用指数增加的值(getElement
,getElement(2)
,getElement(4)
,...)调用getElement(8)
来确定列表的大小,一旦你知道一个慷慨的上限,使用binary search来找到确切的大小。
upper = 2
try:
while True:
getElement(upper)
upper *= 2
except IndexError:
pass
lower = -1
while lower < upper:
middle = (lower + upper) // 2 + 1
try:
getElement(middle)
lower = middle
except IndexError:
upper = middle - 1
print("size is", lower + 1)
通过这种方式,我能够找到包含51166个元素(上限为65536)的列表大小,只需33次调用getElement
。 (如果允许您编写一个尝试某个索引的辅助函数,然后返回try/except
或True
而不是引发异常,我猜你也可以摆脱那些False
。)
答案 1 :(得分:1)
我会尝试二分搜索(半间隔搜索)https://en.wikipedia.org/wiki/Binary_search_algorithm。启动一些大数字,看它是否仍然返回100或异常超出范围。然后增加数字或转到它的0.5 *值等等...阅读维基百科帖子以获得算法的概念。与完全搜索的情况相比,最终的复杂性应该更低。但实施取决于你,看起来像是一个功课:)