Javascript 查找二进制搜索结果的最左重复项
假设我有一个有序数组,其中包含大量重复项:Javascript 查找二进制搜索结果的最左重复项,javascript,arrays,algorithm,binary-search,Javascript,Arrays,Algorithm,Binary Search,假设我有一个有序数组,其中包含大量重复项: var array = [ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, ]; 我还有代码可以在排序数组中对最近值的索引执行二进制搜索: function binaryClosestIndexOf(array, value) { va
var array = [ 1, 1, 1, 1, 1,
2, 2, 2, 2, 2,
3, 3, 3, 3, 3,
4, 4, 4, 4, 4,
5, 5, 5, 5, 5, ];
我还有代码可以在排序数组中对最近值的索引执行二进制搜索:
function binaryClosestIndexOf(array, value) {
var mid,
lo = 0,
hi = array.length - 1;
while (hi - lo > 1) {
mid = (lo + hi) >>> 1;
if (array[mid] > value)
hi = mid;
else
lo = mid;
}
if (value - array[lo] <= array[hi] - value)
return lo;
else
return hi;
}
正如我们所看到的,该算法没有问题,它确实返回了最接近的值。但是它返回了一个有趣的混合指数,从最左边到最右边
我想得到最左边的重复索引。我可以在二进制搜索之后引入一个O(n)搜索,然后遍历数组中的每个值,直到找到一个小于当前值的值。我不想这样做
有没有一种方法可以优雅地执行二进制搜索,最终得到最左边的重复值?对于最右边的值的算法也有额外的积分 您可以使用
Array.prototype.indexOf()
<代码>返回数组。索引数组(值数组[Lo] 是二进制搜索,如果你搜索一个精确的值,你不能保证任何位置(右或左测试),它可能在中间。 由于二进制搜索的工作原理是有一个排序的列表,并减少两个因子,因此查找边索引可能很困难 我可以想出两种方法
如果列表很长,我认为选项2的预期运行时间实际上会比选项1长,因为2*log(n)将是>log(n)+一个常量,除非您知道会有很多重复项。重新排列数据结构以保留值、最左边的位置和计数,即保留数组
var array = [ 1, 1, 1, 1, 1,
2, 2, 2, 2, 2,
3, 3, 3, 3, 3,
4, 4, 4, 4, 4,
5, 5, 5, 5, 5, ];
差不多
var array=[{"v": 1, "l": 0, "c": 5},
{"v": 2, "l": 5, "c": 5},
{"v": 3, "l": 10, "c": 5},
{"v": 4, "l": 15, "c": 5},
{"v": 5, "l": 20, "c": 5}];
其中“v”表示“值”,“l”表示“最左边的索引”,“c”表示“计数”。对值执行二进制搜索,然后“l”表示最左边的索引,“l”+“c”-1表示最右边的索引
如果你建立一个约定,你可以将替代结构缩短一点,而不是{“v”:1,“l”:0,“c”:5},使用[1,0,5],其中对应的项分别是value,最左边的索引和count
vararray=[[1, 0, 5],
[2, 5, 5],
[3, 10, 5],
[4, 15, 5],
[5, 20, 5]];
arr
在哪里定义?您唯一能做的就是按原样执行二进制搜索,然后检查目标是否小于结果。(目标为3.9,得到4)如果是这样的话,您已经有了最左边的4个。但是如果不是这样的话,这意味着您已经有了最右边的4个,因此您必须向上迭代,直到遇到最后一个重复项。@guest271314 Typo!”我可以引入一个O(n)在二进制搜索之后进行搜索,遍历数组中的每个值,直到找到一个小于当前值的值。”,我能问一下为什么O(n)
而它肯定是O(lg(n))
?@user3707125我想进行增量迭代抱歉,我没有想到要进行第二次二进制搜索-这不是很好的编写,也就是说,如果我找到array[I]=target
,然后测试array[--I]
,直到找到为止,这是O(n)
(请注意,这是最糟糕的情况!)。你能说明应该如何使用它吗?
var array=[{"v": 1, "l": 0, "c": 5},
{"v": 2, "l": 5, "c": 5},
{"v": 3, "l": 10, "c": 5},
{"v": 4, "l": 15, "c": 5},
{"v": 5, "l": 20, "c": 5}];
vararray=[[1, 0, 5],
[2, 5, 5],
[3, 10, 5],
[4, 15, 5],
[5, 20, 5]];