二分查找

126 阅读3分钟

关键词: Sorted Array. 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法,可以在数据规模的对数时间复杂度内完成查找。二分查找可以应用于数组,是因为数组具有有随机访问的特点,并且数组是有序的。

二分查找体现的数学思想是「减而治之」,可以通过当前看到的中间元素的特点推测它两侧元素的性质,以达到缩减问题规模的效果。

算法思想: 相比于 整数二分,浮点数二分由于不存在整除操作

在这之前,我想插入一下我们algorithm学习的例子:Divide and Conquer

6033 algorithm 典型例子: deterministic selection Week 7 真的 最好把老师上课的这个例子丢进去。非常漂亮的例子。

二分法其实特别有意思,你能梳理清楚recursive function就行。我读完一文看懂递归 觉得真是醍醐灌顶。之后做题就很轻巧。很感谢

我是一开始就做的Leetcode 4 hard 做完hard其他题真是迎刃而解。很多人说二分查找的边界很难找,但我觉得 很有趣。你要用recursive function 去看他 你就会觉得,哇哦,真的是很简单的问题。

细节:

  1. 在二分法中,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。

278. First Bad Version Easy

注意这俩道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 是为了避免 startend 在接近时出现无限循环。
  • 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 自己做出来的。