Java/二分查找/新模板

二分查找法解决算法问题的新套路

1.写循环体判断的时候使用while (left <right)。
使用 < 而不是 <= 。

2.注意中位数 mid 的赋值有2种:

  • int mid = ( left + right )>>>1; 这是左中位数
  • int mid = ( left + right + 1)>>>1; 这是右中位数

3.如何判断你该使用哪一种中位数:

  • 使用左中位数的情况:
    中位数小于目标值,便可以排除。
  • 使用右中位数的情况:
    中位数大于目标值,便可以排除。

4.如果你使用左中位数,使用如下方式判断:

if(排除左中位数的逻辑){
	left = mid + 1;
}else{
	right = mid;
}

如果你使用右中位数,使用如下方式判断:

if(排除右中位数的逻辑){
	right = mid - 1;
}else{
	left = mid;
}

5.出循环体时,一定是left==right,此时再根据情况返回(比如,找到了,或者找不到)。

这么做的好处

1.你不需要考虑何时用 <= 。
2.判断中位数的操作不放在循环体中。
3.返回的时候不用考虑使用 left 还是 right 。

来个例题试试

LeetCode 第744题 寻找比目标字母大的最小字母
给定一个只包含小写字母的有序数组letters 和一个目标字母 target,寻找有序数组里面比目标字母大的最小字母。
数组里字母的顺序是循环的。举个例子,如果目标字母target = ‘z’ 并且有序数组为 letters = [‘a’, ‘b’],则答案返回 ‘a’。

示例:

输入:
letters = [“c”, “c”, “f”, “j”]
target = “c”
输出: “f”

输入:
letters = [“c”, “f”, “j”]
target = “j”
输出: “c”

注:

letters长度范围在[2, 10000]区间内。
letters 仅由小写字母组成,最少包含两个不同的字母。
目标字母target 是一个小写字母。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-smallest-letter-greater-than-target
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

对应套路,你需要斟酌的仅仅是

1.寻找比目标字母大的最小字母,如果中位数比目标字母小,必须排除啊,使用左中位数。
2.排除左中位数的逻辑:中位数小于或等于目标值。
所以,答案:

class Solution {
    public char nextGreatestLetter(char[] letters, char target) {
        if(target>=letters[letters.length-1])
            return letters[0];
        int l = 0;
        int r = letters.length - 1;
        while (l < r) {
            int mid = (l+r)>>>1;
            if (letters[mid] <= target) {
                l = mid + 1;
            } else {
                r = mid;
            }
        }
        return letters[l];
    }
}

是不是很简单!
如果你不知道这个套路可能要试很久哦!

面试:手撕二分查找

非递归

public class BinarySearch {
    public int search(int[] arr, int target){
        int left = 0;
        int right = arr.length - 1;
        while(left < right){
            int mid = (left + right) >>> 1;
            if(arr[mid] < target){
                left = mid + 1;
            }else{
                right = mid;
            }
        }
        return arr[left] == target ? left : -1;
    }
}

递归

public class BinarySearch {
    public int search(int[] arr, int target){
        return search(arr, target, 0, arr.length - 1);
    }

    private int search(int[] arr, int target, int left, int right) {
        if(left == right)
            return arr[left] == target ? left : -1;
        
        int mid = (left + right) >>> 1;
        
        if(arr[mid] < target)
            return search(arr, target, mid +1, right);
        else
            return search(arr, target, left, mid);

}

参考自:
https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/

©️2020 CSDN 皮肤主题: 岁月 设计师: pinMode 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值