【问题标题】:Comparing Binary search solution with book将二进制搜索解决方案与书籍进行比较
【发布时间】:2018-11-12 14:35:20
【问题描述】:

问题如下:

如果可以循环移动其条目以使其排序,则称数组为循环排序的。例如,图 11.2 中的数组是循环排序的——循环左移 4 会导致排序数组。设计一个O(logN) 算法来查找循环排序数组中最小元素的位置。假设所有元素都是不同的。例如,对于list = [378, 478, 550, 631, 103, 203, 220, 234, 279, 368],返回值应为 4。

该解决方案通过将中间值与 A[n-1] 进行比较来工作 - 根据关系,您可以将搜索范围缩小到具有拐点的列表一侧。

我的解决方案:

def cyclic_sorted_lst(A):
  low, high = 0, len(A) - 1
  while low <= high:
    mid = (low + high) // 2
    if A[mid] < A[high]:
      high = mid 
    elif A[mid] == A[high]:
      return mid 
    else:
      low = mid + 1 

作者解决方案:

def search_smallest(A):
  left, right = 0, len(A) - 1 
  while left < right:
    mid = (left + right) // 2
    if A[mid] > A[right]:
      left = mid + 1 
    else:
      right = mid 
  return left 

我想知道我的解决方案是否会导致任何错误,或者这两个解决方案是否同样好。我的有什么遗漏吗?至少对于问题描述中的示例,它运行良好。

【问题讨论】:

  • 测试这些东西比批判性地分析它们更简单、更快捷。只需随机生成数组并将解决方案的输出与通过数组的简单线性扫描进行比较!这样做只需要五分钟,您会对解决方案的质量感到满意。
  • @Rishav 这是你能给别人的最糟糕的建议。正是这种想法让我在凌晨 2 点醒来,因为网站宕机了。一些目光短浅的人没有批判性地分析,就把一些代码拼凑起来,运行了几个测试,然后说:“好吧,它似乎有效。让我们发布它。”想到有人在研究自动驾驶汽车会听从你的建议,我就不寒而栗。

标签: python algorithm binary-search


【解决方案1】:

根据我的评论,我编写了一个简单的测试生成器来测试您的解决方案。代码如下:

def cyclic_sorted_lst(A):
  low, high = 0, len(A) - 1
  while low <= high:
    mid = (low + high) // 2
    if A[mid] < A[high]:
      high = mid 
    elif A[mid] == A[high]:
      return mid 
    else:
      low = mid + 1

import random
i = 0
while True:
    i += 1
    print(i)
    arr = list(set([random.randint(1, int(1000)) for _ in range(10)]))
    arr.sort()
    length = random.randint(1, len(arr))
    cyclic_arr = arr[length:] + arr[:length]
    print(cyclic_arr)
    if cyclic_sorted_lst(cyclic_arr) != cyclic_arr.index(min(cyclic_arr)):
        print(cyclic_arr, cyclic_sorted_lst(cyclic_arr), cyclic_arr.index(min(cyclic_arr)))
        break

您的代码成功运行了超过 200K 次迭代,因此我非常确信它是正确的。

【讨论】:

  • 绝对不是!这一切都证明你没有找到失败的案例。有无数个可能的数组。再多的测试都无法证明该算法适用于所有情况。随机测试不能代替算法分析。我曾经遇到过一个很少发生的严重错误。有人花了 才遇到这个错误并追踪它。幸运的是,该错误只是关闭了我的网络爬虫,而不是取出电网或其他东西。详情请见stackoverflow.com/q/1148278/56778
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 2022-11-25
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 2014-06-21
  • 2020-10-25
相关资源
最近更新 更多