【二分查找专题】给出四种二分查找的模版
本问题对应课程链接:剑指offer刷题第三期
本次打卡的任务很简单,就是给出四种变形二分查找的模版代码,并且给出了对应的方法名字。
比如对于一个有序数组
arr = [1,2,3,3,3,4,5,5,7],target = 3,那么
1.寻找第一个大于 target 的元素的下标,本案例中4 就是第一个大于 target 的元素 ,下标 = 5。
对应方法名格式为
int upper(int[] arr, int target){
//如果都不存在,则返回-1
}
2.如果数组中存在元素等于 target,则返回最后一个等于target 的元素下标,如果不存在,则返回第一个大于 target 的元素下标。本案例中最后一个等于target的下标 = 4。
对应方法名
int floor_upper(int[] arr, int target){
//如果都不存在,则返回-1
}
3.寻找最后一个小于 target 的元素的下标,本案例中 2 则是最后一个小于 target 的,下标 = 1.
对应方法名格式为
int lower(int[] arr, int target){
//如果都不存在,则返回-1
}
4.如果数组中存在元素等于 target,则返回第一个等于target 的下标,如果不存在,则返回最后一个小于 target 的元素的下标。本案例中第一个等于target的下标 = 2。
对应方法名格式为
int floor_lower(int[] arr, int target){
//如果都不存在,则返回-1
}
注意:大家给了模版之后,选择一个适合自己的模版,以后都用这个模版,忘了怎么办?这玩意的区别就是要么是大于,要么是大于等于,你如果记混了,可以随便找一组数据试一下,就能分辨出来了,我笔试时都这样干,,,
共以下 26 个回答
“`java
public static int upper(int[] arr, int target){
// 二分查找需要想清楚的点
int l = 0;
int r = arr.length – 1;
// 判断特殊情况
if(arr[r] <= target){ return -1; } //[l,r],,在我们二分查找的过程中,不断缩小我们的查找范围,直到范围里面只有一个元素,那个就是我们要找的元素了 while(l < r){ int mid = (r - l) / 2 + l; if(arr[mid] > target){
//[l ,mid, r]
r = mid;
} else if(arr[mid] == target){
l = mid + 1;
}else {//arr[mid] < target l = mid + 1; } } return l; }
C++实现
“`C++
int upper(int[] arr, int target){
int l = 0;
int r = arr.length – 1;
if (arr[r] < = target) { return -1; } while (l < r) { int mid = l + (r - l)/2; if (arr[mid] > target){
r = mid;
} else if (arr[mid] == target){
l = mid + 1;
} else {
l = mid + 1;
}
}
return l;
}
“`
本质上都是不断缩小左右范围,操作的不同主要体现在arr[mid]target上:
【思路】-
【复杂度】时间O(logn),空间O(1)
二分法模板
package org.example;
public class BanarySort {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 3, 3, 4, 5, 5, 7};
int target = 3;
int index = lastLess(arr, target);
System.out.println(“index = ” + index + “, value = ” + arr[index]);
}
时间复杂度O(logn), 空间复杂度O(1)
思路:控制边界细节
1.寻找第一个大于target的下标,往右寻找 l = mid + 1
2.寻找最后一个等于target的下标,是第一个大的前一个
3.寻找最后一个小于target的下标,往左寻找r = mid – 1
4.寻找第一个等于target的下标,根据小于的下标 + 1
4种二分查找
二分查找
感觉题目要求奇奇怪怪的,很难读懂
帅地才是yyds
MYb站up五点七边的二分查找
要找第一个大于的,就缩小左边界;要找第一个小于的,就缩小右边界。
看完讲解会了
1. 确定搜索范围
2. 不断缩小范围
3. 判断特殊情况
给一个常用的二分模板:
1.寻找第一个大于 target 的元素的下标
本案例中4 就是第一个大于 target 的元素 ,下标 = 5。
2.如果数组中存在元素等于 target,则返回最后一个等于target 的元素下标,如果不存在,则返回第一个大于 target 的元素下标。
本案例中最后一个等于target的下标 = 4。
3.寻找最后一个小于 target 的元素的下标
本案例中 2 则是最后一个小于 target 的,下标 = 1.
4.如果数组中存在元素等于 target,则返回第一个等于target 的下标,如果不存在,则返回最后一个小于 target 的元素的下标。
本案例中第一个等于target的下标 = 2。