关键词: Sorted Array. 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法,可以在数据规模的对数时间复杂度内完成查找。二分查找可以应用于数组,是因为数组具有有随机访问的特点,并且数组是有序的。
二分查找体现的数学思想是「减而治之」,可以通过当前看到的中间元素的特点推测它两侧元素的性质,以达到缩减问题规模的效果。
算法思想: 相比于 整数二分,浮点数二分由于不存在整除操作
在这之前,我想插入一下我们algorithm学习的例子:Divide and Conquer
6033 algorithm 典型例子: deterministic selection Week 7 真的 最好把老师上课的这个例子丢进去。非常漂亮的例子。
二分法其实特别有意思,你能梳理清楚recursive function就行。我读完一文看懂递归 觉得真是醍醐灌顶。之后做题就很轻巧。很感谢
我是一开始就做的Leetcode 4 hard 做完hard其他题真是迎刃而解。很多人说二分查找的边界很难找,但我觉得 很有趣。你要用recursive function 去看他 你就会觉得,哇哦,真的是很简单的问题。
细节:
- 在二分法中,
int mid = start + (end -start)/2;mid的求法最好用这个,因为start和end的数值可能过大,(start + end)/2这种会导致int溢出。
题库
二分查找力扣题库
704. Binary Search Easy
用recursive function做出来的time/space complexity 都是O(logn) 可以用while loop 去减低Space Complexity。
注意这俩道easy题,都要用while loop去做。自己思考一下如何快速判断能用while做。
35. Search Insert Position Easy
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int end = nums.size() -1, start = 0;
if(nums[end] < target) return end+1;
if(nums[start] > target) return start;
while(start < end){
int mid = start + (end -start)/2;
if(nums[mid] > target) end = mid;
else if(nums[mid] == target) return mid;
else start = mid+1;
}
return start;
}
};
69. Sqrt(x) Easy 这个很有意思,这个被丢到了二分法的总结里,但是我却不能第一时间做出来。
35题和69题很有趣。35题:寻找第一个大于等于target位置的数值。69题:寻找第一个数的平方小于等于target的数值。这俩题是一个类型的题。在官方解答中都做出了pivot这个小东西。但我在做的时候瞎蒙对了35题。很有意思。
自己在做题的时候太喜欢蒙了,在做题的时候一定要带着案例去套一遍。
class Solution {
public:
int mySqrt(int x) {
if(x == 0) return x;
int start = 1, end = x/2;
while(start < end){
int mid = start + (end-start)/2 +1;
if(mid <= x/mid) start = mid;
else end = mid-1;
}
return start;
}
};
总结
- LeetCode 69 中使用
mid = start + (end-start)/2 + 1是为了避免start和end在接近时出现无限循环。 - LeetCode 35 中使用
mid = start + (end-start)/2是因为在查找过程中不需要额外的偏移,算法能够正常收敛到目标位置。
这里还是不是特别懂,复习记得回看。
33. Search in Rotated Sorted Array Medium
自己没画图就写就乱错,错了四次。 一定要自己画一下具体的图:俩个情况:一个是直线,一个是俩个线段(nums[start]>nums[end])。看着图, 画nums[mid]去分情况讨论。然后再写code
自己都没弄清楚就瞎写 那就是猛猛出错呀。
34. Find First and Last Position of Element in Sorted Array Medium 自己做出来的。