在仅包含1和0的数组中找到第一个1的索引,所有0都在数组的左侧,所有1都在右侧?

时间:2019-06-16 23:33:26

标签: python algorithm

任务是在仅包含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

这给了我无限循环。我不明白我在做什么错。

3 个答案:

答案 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