记录一下二分查找算法
力扣题目链接: https://leetcode.cn/problems/search-insert-position/
二分难写之处就在于对区间的把握程度上!!!
根据上述力扣题目来写两种区间的解法!
题目:搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法
示例1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例3:
输入: nums = [1,3,5,6], target = 7
输出: 4
提示:
- 1 <= nums.length <= 104
- 104 <= nums[i] <= 104 nums 为 无重复元素 的 升序 排列数组
- 104 <= target <= 104
思路:
用示例二举例。mid的初始值 = 1 nums[mid] > target,所以R = mid -1, R = 0;
再计算mid值, mid = 0 ,nums[mid] < target, L = mid +1, L = 1, 此时的L > R ,不满足循环的条件,退出循环。
所以此时我们可以看到,R = 0,L= 1,**而我们要返回的结果就是1,**那岂不是,直接返回 L 或者 R + 1 就对了呀!
第一种解法:[L,R] 左闭右闭
class Solution {
public int searchInsert(int[] nums, int target) {
int L = 0;
int R = nums.length-1;
while(L <= R){
int mid = L + (R - L)/2;
if(nums[mid] == target){
return mid; // 找到就直接返回即可
}else if(nums[mid] > target){
R = mid - 1;
}else{
L = mid + 1;
}
}
return R + 1; // 或者 L 均可
}
}
第二种解法:[L,R) 左闭右开
其实 左闭右开 你就 死记住 他 比 右闭 多算了一个数而已!!!
右闭需要R = mid - 1, 而右开就压根不需要!!!直接 R = mid即可
因为右闭的mid这个元素已经被用过了,所以就mid - 1了!!!
而右开的mid的这个元素,还未被使用呢!!所以R = mid
因为右开始终比右闭多一个数。
class Solution {
public int searchInsert(int[] nums, int target) {
int L = 0;
int R = nums.length;
while(L < R){
int mid = L + (R - L)/2;
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
R = mid;
}else{
L = mid + 1;
}
}
return R;
}
}
OK ,打完收工!