二分查找法解决算法问题的新套路
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-/