LeetCode-Solutions中的数组上界查找算法解析
什么是数组上界查找
数组上界查找(upper bound)是一种常见的二分查找变体,用于在已排序的数组中查找目标值的最后一个出现位置。与标准二分查找不同,上界查找返回的是目标值在数组中的"上边界",即最后一个等于目标值的元素索引。
算法实现解析
这个实现为JavaScript/TypeScript的Array原型添加了一个upperBound
方法,使得所有数组实例都可以直接调用这个方法进行上界查找。
时间复杂度分析
- 时间复杂度:O(logn),标准的二分查找时间复杂度
- 空间复杂度:O(1),仅使用了常数级别的额外空间
代码结构解析
declare global {
interface Array<T> {
upperBound(target: number): number;
}
}
这部分代码使用TypeScript的声明合并特性,为全局Array接口添加了upperBound
方法声明,使得所有数组实例都可以调用这个方法。
核心算法实现
Array.prototype.upperBound = function(target: number) {
const check = (x: number) => {
return this[x] > target;
};
let left = 0, right = this.length-1;
while (left <= right) {
const mid = left+((right-left)>>1);
if (check(mid)) {
right = mid-1;
} else {
left = mid+1;
}
}
return left-1 >= 0 && this[left-1] === target? left-1 : -1;
};
关键点解析
-
检查函数(check):定义了一个辅助函数,用于判断当前中间值是否大于目标值
-
二分查找循环:
- 初始化左右指针为数组的首尾
- 计算中间位置时使用
left+((right-left)>>1)
,这是防止整数溢出的安全写法,等价于Math.floor((left+right)/2)
- 根据检查函数的结果调整搜索范围
-
结果处理:
- 循环结束后,
left
指向第一个大于目标值的元素 left-1
就是目标值的上界位置- 需要验证该位置确实等于目标值,否则返回-1
- 循环结束后,
实际应用场景
这种上界查找算法在以下场景中非常有用:
- 统计排序数组中某个值的出现次数(结合下界查找)
- 在有序数据集中查找某个范围的边界
- 实现类似C++ STL中的upper_bound功能
算法优化点
- 边界条件处理:算法已经考虑了目标值不存在的情况,返回-1
- 整数溢出防护:中间值计算方式避免了潜在的整数溢出问题
- 类型安全:虽然示例中使用number类型,但可以轻松扩展为泛型实现
与其他查找算法的比较
-
与标准二分查找的区别:
- 标准二分查找返回任意一个匹配项
- 上界查找返回最后一个匹配项
-
与下界查找(lower bound)的区别:
- 下界查找返回第一个等于或大于目标值的位置
- 上界查找返回最后一个等于目标值的位置
总结
这个数组上界查找实现展示了如何高效地在已排序数组中查找特定值的边界位置。通过扩展JavaScript数组的原型,我们为所有数组实例添加了这一实用方法,使得相关操作更加便捷。理解这种查找变体对于解决LeetCode中的许多搜索类问题非常有帮助。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考