假设我有0和1的数组:前n个(可能是n = 0)元素是0,其他元素是1(例如[0,0,1,1,1])。 但我看不到元素。我可以要求在某个位置显示元素。如果事实证明我打开两个1(在任何时候)我必须停止。什么算法导致我找到具有最小数量的开放元素的0的最后位置?
答案 0 :(得分:0)
第一个猜测可能是做二分法搜索:尝试使用中间元素将搜索空间减半。然而,事实证明,鉴于可用的次数有限,这不是一个很好的策略;如果你的第一个猜测结果是1,那么唯一安全的策略是从最大的已知安全位置线性开始,这将是开始。这是O(n)的最坏情况,你也可以从前面扫描得到。当然,我们可以做得更好。
如果我们在位置sqrt(n),2sqrt(n),...,n处尝试元素,如果我们在某个点找到1,则会线性迭代怎么办?
n = 100的示例,分为27。
check array[10]; value 0, so continue.
check array[20]; value 0, so continue.
check array[30]; value 1, so switch to linear.
check array[21]; value 0, so continue.
check array[22]; value 0, so continue.
check array[23]; value 0, so continue.
check array[24]; value 0, so continue.
check array[25]; value 0, so continue.
check array[26]; value 0, so continue.
check array[27]; value 1, so answer 26.
对于n = 100,最坏的情况是99处的分割,并检查10 + 9 = 19的值。检查值的上限是2sqrt(n),即O(sqrt(n)),对于朴素的线性方法,渐近优于O(n)。
你能做得更好吗?我持怀疑态度。该方法通过平衡快速方法(跳过多于一个)和慢速方法(线性扫描)的复杂性来实现加速,使得它们在最坏的情况下具有相同数量的步骤。由于整体复杂性是这两者的总和,并且因为一切看起来都是非常对称的,所以我怀疑这是最优的 - 任何其他跳过方式然后线性扫描在某些情况下可能会做得更好,但在其他情况下必须做得更糟。例如,每次加倍跳过 - 尝试2,4,8,...,n - 具有O(n)最坏情况复杂度,因为您在快速步骤中尝试log(n)值,并且在n / 2值中尝试缓慢的步骤(如果你尝试n时失败,你必须检查上面的所有内容~n / 2)。
答案 1 :(得分:-1)
使用循环逐个打开元素,然后使用if语句检查元素的值。如果位置j的元素为1,则退出循环,最后的0位于位置j-1