更新1(10月16日):原始代码中有一些逻辑错误已得到纠正。现在,下面的更新代码将为所有符合特殊列表标准的列表L,S.T产生正确的输出。
我正在尝试减少以下功能的运行时间:
“ firstrepeat”函数接收特殊列表L和一个索引,并产生最小索引,使得L [i] == L [j]。换句话说,无论L [i]处的元素是什么,“ firstrepeat”函数都会返回该元素在列表中首次出现的索引。
列表L有什么特别之处?:
列表先减小(或保持不变),然后又增大(或保持不变)。
示例:
L = [4,2,0,1,3]
L = [3,3,3,1,0,7,8,9,9]
L = [4,3,3,1,1,1]
L = [1,1,1,1]
示例输出:
假设我们有L = [4,3,3,1,1,1]
firstrepeat(L,2)将输出1
firstrepeat(L,5)将输出3
我有以下代码。我相信复杂度是O(log n)或更好(尽管我可能会遗漏一些东西)。我正在寻找提高时间复杂度的方法。
def firstrepeat(L, i):
left = 0
right = i
doubling = 1
#A Doubling Search
#In doubling search, we start at one index and then we look at one step
#forward, then two steps forward, then four steps, then 8, then 16, etc.
#Once we have gone too far, we do a binary search on the subset of the list
#between where we started and where we went to far.
while True:
if (right - doubling) < 0:
left = 0
break
if L[i] != L[right - doubling]:
left = right - doubling
break
if L[i] == L[right - doubling]:
right = right - doubling
doubling = doubling * 2
#A generic Binary search
while right - left > 1:
median = (left + right) // 2
if L[i] != L[median]:
left = median
else:
right = median
f L[left] == L[right]:
return left
else:
return right