二分法总结

作者: 一个小小小孩呢 | 来源:发表于2020-10-28 21:41 被阅读0次

二分法总结

二分法貌似简单,实则很多细节,需要多加注意才能写对。

应用

1 在单调递增数组中确认是否有指定target


    public int binarySearch(int[] nums, int target)
    {
        int left = 0 ;
        int right = nums.length - 1;
        int mid = 0;

        while(left <= right)
        {
            mid = left + ((right - left) >> 1);
            if (nums[mid] == target)
            {
                return mid;
            }
            else if (nums[mid] < target)
            {
                left = mid + 1 ;
            }
            else
            {
                right = mid - 1 ;
            }
        }
        return -1 ;
    }

2 在单调递增数组中查找第一个为target的值(每个值不唯一)

    public int binarySearchFirst(int[] nums , int target)
    {
        int left = 0 ;
        int right = nums.length - 1 ;
        int mid = 0 ;

        while(left < right)
        {
            mid = left + ((right - left) >> 1);
            if (nums[mid] < target)
            {
                left = mid + 1 ;
            }
            else
            {
                right = mid;
            }
        }

        if (nums[right] == target)
        {
            return left;
        }
        else
        {
            return -1 ;
        }
    }

3 在单调递增数组中查找最后一个为target的值(每个值不唯一)

    public int binarySearchLast(int[] nums , int target)
    {
        int left = 0 ;
        int right = nums.length  - 1 ;
        int mid = 0 ;

        while(left < right)
        {
            mid = left + ((right - left) >> 1) + 1;
            if (nums[mid] <= target)
            {
                left = mid;
            }
            else
            {
                right = mid - 1;
            }
        }
        if (nums[left] == target)
        {
            return left;
        }
        return -1 ;
    }

当然,还有如下变种

4 查找单调数组中第一个大于target的值

    public int binarySearchFirstGreaterThan(int[] nums , int target)
    {
        int left = 0 ;
        int right = nums.length - 1;
        int mid = 0 ;

        while(left < right)
        {
            mid = left + ((right - left) >> 1);
            if (nums[mid] <= target)
            {
                left = mid + 1 ;
            }
            else
            {
                right = mid;
            }
        }

        if (nums[left] > target)
        {
            return nums[left];
        }
        else
        {
            return -1 ;
        }
    }

5 查找单调数组中最后一个小于target的值

    public int binarySearchLastSmallerThan(int[] nums , int target) {
        int left = 0;
        int right = nums.length - 1;
        int mid = 0;

        while (left < right) {
            mid = left + ((right - left) >> 1) + 1;
            if (nums[mid] >= target) {
                right = mid - 1;
            } else {
                left = mid;
            }
        }

        if (nums[right] < target) {
            return nums[right];
        }

        return -1;
    }

总结

二分法核心要点是每次循环一定需要让left或者 right有一个值发生变动,否则就会出现死循环,写出不正确的二分法。
所以个人做法一般如下:

  • 确定锚点
    一般求第一个出现的值用left,最后一个值用right来锚住答案;针对锚点分支的条件一定要激进,需要确保每次进入分支一定要显示的+1或者-1来发生偏移

  • 确定 mid偏移

mid = left + ((right - left) >> 1) + 1; // 右偏移
mid = left + ((right - left) >> 1)  ; // 左偏移

如果用left作为锚点,则使用左偏移将right逐渐拉至left 处退出循环,反之亦然。该偏移点分支条件就是锚点分支的简单else,偏移特性使得其一定会发生偏移。这样就确保了每次循环可以必然发生一侧的偏移,防止两侧都不动进入死循环

  • 返回值检查
    最后在返回前需要检查答案是否满足条件,不满足返回-1等无效值。

后话

务必务必务必每次循环一定需要让left或者 right有一个值发生变动!!!
之前的例子中,二分法用来直观的搜索值,但是其在如下场景中也是很多见的:
在一个可以确定上下界的单调解空间中,二分加速处理速度。
个人认为二分法的核心就是在单调解空间中加速搜索target

相关文章

  • binary_search_special

    二分法总结参考:http://blog.csdn.net/ebowtang/article/details/507...

  • 二分法总结

    二分法总结 二分法貌似简单,实则很多细节,需要多加注意才能写对。 应用 1 在单调递增数组中确认是否有指定targ...

  • 中位数问题

    0X00 总结 4. Median of Two Sorted Arrays 二分法去做, 每次删除一个列表的元素...

  • 冒泡排序、选择排序和二分法查找

    冒泡排序 选择排序 二分法查找 概念 1.使用二分法好处: 可以加快寻找的效率。2.使用二分法特点: 二分法...

  • 二分法查找

    二分法基本查找 二分法遍历查找

  • 二分法查找

    二分法查找的前提是数组必须排序!!!二分法查找的前提是数组必须排序!!!二分法查找的前提是数组必须排序!!!二分法...

  • 二分法总结

    待补充。 Leetcode上Binary Search题目(按frequency排序):4 Median of T...

  • 手绘日常

    人物素描 今天重点讲二分法 二分法的重要性

  • python-递归-二分法

    二分法

  • 34 Search for a Range

    二分法

网友评论

    本文标题:二分法总结

    本文链接:https://www.haomeiwen.com/subject/qqxhvktx.html