给定一个非负整数数组,例如:
例子 3 0 0 4 7 9 0 0 0 0 11 15 0 19 20 0 0 31 40 0
对于 k=4
如果 k 是常数但我们不知道,我们需要函数 kAlmostSearch(int[] a, int num)。
我正在尝试修改二分搜索,但不确定我到底该怎么做。
我的目标是找到最有效的时间+空间方式来做。
您可以使用滑动窗口策略来调整二分查找以解决最多 k 个连续零的存在。目标是对这个更新后的数组执行二进制搜索,使用每个大小为 (k+1) 的窗口作为单个元素。
如何将这个策略付诸实践如下:
说明:
我们为每次二分搜索迭代计算当前窗口的中间索引。如果中间元素为零,中间索引将更改为向右跳过最多 k 个连续零。这是因为数组在存在最多 k 个连续零的情况下并不是严格递增的,我们必须在搜索中考虑到这一点。
与此类似,如果中间元素不为零,我们将中间索引更改为向左跳过最多 k 个连续零。这是因为出现在非零元素左侧的任何零必须是最大允许的 (k+1) 个连续零的一部分。
我们通过将每个大小为 (k+1) 的窗口视为单个元素,保证二分查找方法在 O(log n) 时间内继续执行,即使数组中有多达 k 个连续的零。
对于 py 中的 ex
def kAlmostSearch(a, num):
n = len(a)
left, right = 0, n - 1
k = 4 # example value, can be any non-negative integer
while left <= right:
m = (left + right) // 2
# Adjust middle index to skip over up to k sequential zeroes
if k > 0 and a[m] == 0:
m = min(m + k, right)
while m < right and a[m] == 0:
m += 1
elif k > 0 and a[m] != 0:
m = max(m - k, left)
while m > left and a[m] == 0:
m -= 1
if a[m] == num:
return m
elif a[m] < num:
left = m + 1
else:
right = m - 1
return -1