任务是在仅包含1和0的数组中查找第一个1的索引,所有0都位于数组的左侧,所有1都位于右侧。
例如,如果列表为[0,0,0,0,1,1],答案将为4。
所用时间必须是对数的。
我尝试实现以下逻辑:如果中间数字为0,我们只看列表的后半部分。另一方面,如果中间数字为1,则仅查看列表的前半部分。我们一直这样做,直到只剩下一个数字。
def first1(lst):
start_val=0
end_val=len(lst)
midpoint=(end_val+start_val)//2
while end_val-start_val>1:
if lst[midpoint]==1:
endval=midpoint-1
midpoint=start_val+end_val//2
else:
startval=midpoint+1
midpoint=start_val+end_val//2
return midpoint
这给了我无限循环。我不明白我在做什么错。
答案 0 :(得分:1)
阅读本文时,您会踢自己。初始化变量start_val和end_val,但将endpoint + 1分配给startval和endval(变量名中没有下划线)。
否则,它可以正常工作。我没有立即看到它,所以我在循环中添加了一条print语句以及1秒的延迟,因此我可以看到发生了什么。另外,我对您的代码进行了一些格式化,以使其更具可读性,主要是遵循在变量和运算符之间放置空格的建议。
import time
def first1(lst):
start_val = 0
end_val = len(lst)
midpoint = (end_val + start_val) // 2
while end_val - start_val > 1:
if lst[midpoint] == 1:
end_val = midpoint - 1
midpoint = (start_val + end_val) // 2
else:
start_val = midpoint + 1
midpoint = (start_val + end_val) // 2
print(start_val, midpoint, end_val)
time.sleep(1)
return midpoint
print(first1([0,0,0,0,1,1]))
答案 1 :(得分:1)
出现此问题的原因是因为在线
endval=midpoint-1
和行
startval=midpoint+1
您在start_val和end_val中缺少下划线。 但是由于方法不同,如果长度不是2的幂,则无法使用
答案 2 :(得分:0)
您可以将您的数组视为已排序,并使用二进制搜索算法。这会给您O(log(N))时间复杂度。
例如:
from bisect import bisect_left
a = [0,0,0,0,1,1]
p = bisect_left(a,1)
print(p) # 4
如果不允许使用Python模块,则可以编写自己的二进制搜索:
def find1(array):
lo,hi = 0,len(array)-1
while hi>=lo:
mid = (hi+lo)//2
if array[mid]: hi = mid-1
else: lo = mid+1
return hi+1
find1([0,0,0,0,1,1]) # 4