繁体   English   中英

在 O(log(n)) 时间内查找数组中缺失的数字

[英]Find missing numbers in array in O(log(n)) time

我得到了两个 arrays A 和 B,其中 A 完全用正整数填充,B 是 A,其中一些恒定数量的元素变成了零。 我还得到了一个任意 function ,它接受一个数组并给出从 a 到 b 的 O(1) 中数组的总和,其中 a 和 b 是数组中的索引。

我应该设计一种算法,在 O(log(n)) 时间内将数组 B 转换为数组 A,但我很难理解这是如何实现的。

我想出了一个 O(n) 的解决方案,我只需将 A 的索引与 B 的索引进行比较。如果它们相同,我继续循环,如果它们不同,我更新B[i] 为 A[i]。 我看不到改善这一点的方法,特别是如果 arrays 未排序。

对零元素的二进制搜索。 (提示:如果sum(A, lo, hi) ≠ sum(B, lo, hi)则该范围至少包含一个零元素。如果您有这样的范围,则可以将其分成两半:如果第一个half 包含零元素继续前半部分,否则继续下半部分。当你到达一个元素范围时停止。

让我们调用给定的 function sum 如前所述,您可以将其称为sum(array, i, j) ,它将返回array[i] +... + array[j-1]的总和。 我假设该范围不包括j本身的索引,但如果包含它,推理是相同的。

让我们也称kB中零的数量。

现在,您可以使用二分搜索找到B中最左边的 0,方法是比较sum(A, 0, i)sum(B, 0, i) ,同时根据二分搜索方法改变i 然后,当找到这些总和不相等的最低索引时,您就知道B[i]为零,并且在O(logn)时间内。

因此,然后将相应的(非零)值从A[i]分配给B[i] 然后重复这k次。 由于k是常数,它不会影响时间复杂度:当k是常数时, O(klogn)仍然是O(logn) ,例如 2。

这是 JavaScript 中的一个实现,带有示例输入,并且k=2

 // Implementation of the hidden function, which (contrary to this implementation) // should run in constant time function sum(arr, i, j) { result = 0; while (i < j) { result += arr[i++]; } return result; } // example let a = [3,2,6,7,1,9,8,5]; let b = [3,2,0,7,1,9,0,5]; let n = a.length; let k = 2; for (let times = 0; times < k; times++) { // Apply binary search let low = 0; let high = n; while (low < high) { let mid = (low + high + 1) >> 1; if (sum(a, 0, mid) == sum(b, 0, mid)) { low = mid; } else { high = mid - 1; } } // Found index where zero is at: b[low] = a[low]; } console.log(b);

k未知时

...那么它不是恒定的,而是可变的。 然后时间复杂度变为O((k+1)logn) ,即O(klogn) ,并且循环必须继续进行,直到搜索不再找到零(在第 (k+1)迭代中):

 // Implementation of the hidden function, which (contrary to this implementation) // should run in constant time function sum(arr, i, j) { result = 0; while (i < j) { result += arr[i++]; } return result; } // example let a = [3,2,6,7,1,9,8,5]; let b = [3,2,0,7,1,9,0,5]; let n = a.length; // no definition of k here while (true) { let low = 0; let high = n; while (low < high) { let mid = (low + high + 1) >> 1; if (sum(a, 0, mid) == sum(b, 0, mid)) { low = mid; } else { high = mid - 1; } } if (low >= n) break; // no zero found // Found index where zero is at: b[low] = a[low]; } console.log(b);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM