给出一个可以分为两部分的列表L [:z]和L [z:],以使第一个不增加,第二个不减少并且可以包含或不包含重复元素,请创建一个这样的功能:
输入:
输出:
复杂性和要求
我有以下内容:
def findmin(L, k = None):
left = 0
right = len(L)-1
foundmin = False
while not foundmin:
mp = (left + right)//2
if L[mp] > L[mp+1]:
left = mp
elif L[mp-1] < L[mp]:
right = mp+1
else:
return L[mp]
它仅适用于某些列表,例如: L = [9,9,4,3,2,1,7,7,10,10]
但是它不适用于以下列表: L = [6,5,4,3,3,3,3,3,3,3,3,3,1,7,7,7,7]
我尝试修改该功能以容纳重复的元素而无济于事。我也没有看到函数的输入k的效用。有想法吗?
答案 0 :(得分:2)
此代码在O(logn)中运行,并且不使用k
参数。
这是一种类似于@coldspeed的二进制搜索。
def find_min(l, k=None):
left = 0
right = len(l) - 1
while left <= right:
middle = (left + right) // 2
if l[middle] < l[left] or (l[middle] == l[left] and middle > left):
left = middle
elif l[middle] < l[right] or (l[middle] == l[right] and middle < right):
right = middle
else:
return l[middle]
答案 1 :(得分:1)
解决方案的问题是,如果mp两侧的数字等于mp,则您的算法将输出L [mp]。因此,在第二种情况下,它输出3。一个简单的事情是检查下一个不相等的数字,而不是仅检查相邻的不相等数字。
修改后的解决方案:
def findmin(L, k = None):
left = 0
right = len(L)-1
foundmin = False
while left<right:
print(left, right)
mp = (left + right)//2
next_diff = mp+1
while(next_diff < len(L)-1 and L[next_diff] == L[mp]):
next_diff+=1
if L[mp] > L[next_diff]:
left = next_diff
elif L[mp] <= L[next_diff]:
right = mp
return L[left]
P.S:尽管在这种情况下,复杂度变为O(k * log n)。