二分查找汇总1
程序员文章站
2024-03-17 14:21:58
...
二分查找
二分查找是常用的查找算法之一,凡是看见有关log时间复杂度的要求,都要想到二分查找,前提是搜索列表是有序的,才能应用二分查找。
这里我记录一篇写的比较好的二分查找的文章,以备后续反复学习。
二分查找总结
左开右闭二分查找
对于寻找左右边界的二分搜索,常见的手法是使用左闭右开的「搜索区间」,在刷力扣的一道题中遇见了采用左开右闭的方式去寻找元素的右分割线的位置,,因此自己简单做了一点代码去实现该想法。
package com.heu.wsq.leetcode;
/**
* @author wsq
* @date 2021/1/20
*/
public class BinarySearch {
public int customSearch(int[] nums, int target){
int n = nums.length;
// 确定搜索区间
// 注意:这时候只是确定了区间的边界,但是还没有确定区间的开闭情况
int left = 0;
int right = n;
// while中取等号,可以实现双闭
while (left < right) {
// 求中间值,采用left + (right - left) / 2的方式可以防止溢出
// 由于java中的向下取整同时暗示着,取下限,而不取上限,确定区间 是左闭右开的[left, right)
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
// 找到目标值,直接返回
return mid;
}else if (nums[mid] < target){
// 中间值小于目标值,证明目标值可能在右边
// 由于是左闭右开的,因此下一步的搜索区间应该是[mid + 1, right)
left = mid + 1;
}else if (nums[mid] > target){
// 中间值大于目标值,证明目标值可能在左边
right = mid;
}
}
return -1;
}
/**
* 左开右闭的方式查找
*/
public int bs2(int[] nums, int target){
int n = nums.length;
// 搜索 1 - n 中是否存在
int left = 0;
int right = n;
while(left < right){
int mid = (left + right + 1) / 2;
if (nums[mid - 1] == target){
return mid - 1;
}else if (nums[mid - 1] < target){
left = mid;
}else if (nums[mid - 1] > target){
right = mid - 1;
}
}
return -1;
}
public static void main(String[] args) {
int[] nums = {0, 1, 2, 4, 5, 7, 9};
int target = 5;
BinarySearch bs = new BinarySearch();
int ansPos = bs.customSearch(nums, target);
System.out.println("the pos of target is " + ansPos);
// 这里我验证一下,左开右闭的效果
int ans = bs.bs2(nums, target);
System.out.println("" + ans);
}
}
上一篇: 求解带权有向图的最短路径