二分查找算法的简单学习笔记
1、算法解释
二分查找
- 又称二分法或折半查找
- 并不一定是对半划分,只是分成两部分取其中一部分继续查找
- 二分查找的时间复杂度为O(logn)
定义区间开闭性————两个小Tips
- 尝试熟练,左闭右开(满足C++、Python等语言习惯);或左闭右闭(处理边界条件)。
注:尽量保持一种写法 - 刷题时考虑:当前的写法,最后一个数或两个数是否会陷入死循环;如果会,则换种写法
2、求开方问题
解题思路
- 根据牛顿迭代思路设定划分区间的边界
Java解答
class Solution {
public int mySqrt(int x) {
if(x == 0 || x == 1) return x;
long a = (long) x / 2;
while (a * a > x) {
a = (a + x / a) / 2;
}
return (int)a;
}
}
3、查找区间问题
① LeetCode 34 在排序数组中查找元素的第一个和最后一个位置
解题思路
- 先来查找左边界,从左往右找到的第一个不小于x的数
- mid为区间的中点mid = l + r >> 1; 判断nums[mid]是否小于target
- 小于则代表答案在右边且不包含mid这个点
- 否则就代表答案在左边且包含mid这个点
- mid为区间的中点mid = l + r >> 1; 判断nums[mid]是否小于target
- 右边界是从左往右找到的第一个不大于x的数
- mid为区间的中点mid = l + r + 1 >> 1;(加1为了防止死循环);判断nums[mid]是否小于等于target;
- 小于等于则代表答案在右边且包含mid这个点
- 否则就代表答案在左边且不包含mid这个点
- mid为区间的中点mid = l + r + 1 >> 1;(加1为了防止死循环);判断nums[mid]是否小于等于target;
Java解答
class Solution {
public int[] searchRange(int[] nums, int target) {
if(nums.length == 0)
return new int[]{
-1, -1};
int l = 0, r = nums.length - 1;
while(l < r) {
int mid = r + l >> 1;
if(nums[mid] >= target)
r = mid; //代表答案在左边且包含mid这个点
else
l = mid + 1; //代表答案在右边且不包含mid这个点
}
int left = l;
if(nums[left] != target) //如果target在数组不存在
return new int