一、二分查找
二分查找也叫折半查找,每次查找缩减当前元素量的一半,这种查找效率是很惊人的
时间复杂度:
假设我们有n个数据,查找一次,元素量变为:2/n;查找k次后的区间:
n/2k,等比数列,当n/2k = 1时,k就是总的缩小次数,=> O(K) = logn
二、二分查找的递归,非递归,面试题
非递归:
/**
*二分查找非递归方式
* @param arr 查找的数组
* @param val 要查找的值
* @return
*/
public static int nBinarySearch(int[]arr,int val){
int low = 0;//第一个元素下标
int hight = arr.length-1;//最后一个元素下标
while (low<=hight){//不加等于号,会不判断low==hight所在元素
int mid = low + (hight-low)/2;
//mid = (low + hight)>>1 low,hight之和可能超过int范围
if (arr[mid]>val){//查找元素小于中间值
hight = mid-1;
}else if (arr[mid]<val){
low = mid + 1;
}else {
return mid;
}
}
return -1;
}
递归:
/**
* 二分查找递归方法
* @param arr 数组
* @param val 要查找的值
* @param low 初始首元素下标
* @param hight 初始末元素下标
* @return
*/
public static int BinarySearch(int[]arr,int val,int low,int hight){
if (low >hight){
return -1;
}
int mid = low + (hight-low)/2;
if (arr[mid]>val){
return BinarySearch(arr,val,low,mid-1);
}else if (arr[mid]<val){
return BinarySearch(arr,val,mid+1,hight);
}else {
return mid;
}
}
腾讯面试题:
//TODO:腾讯面试题
// 小Q父母要出去N天,留了M颗糖,条件:小q吃糖数大于等于前一天的吃糖数的一半,且N天每天都要吃糖
//问:第一天小Q最多可以吃多少颗糖
public static int Search(int n,int m){
if (n == m){//天数等于糖数,那就只有每天一个了
return 1;
}
int low = 1;
int hight = m;
while (low<=hight){
int mid = low + (hight-low)/2;
int sum = Sum(mid,n);
if (sum<m){
low = mid+1;
}else if (sum>m){
hight = mid-1;
}else {
return mid;
}
}
return -1;
}
public static int Sum(int mid,int N){
int sum = 0;
for (int i = 0;i<N;i++){
sum+=mid;
mid = (mid+1)/2;//向上取整
}
return sum;
}
测试程序:
public static void main(String[] args) {
int[]arr = {2,1,3,6,5,7,8};
//二分查找针对的是对有序序列,先对数组排序
Arrays.sort(arr);// 1 2 3 5 6 7 8
int result = nBinarySearch(arr,6);
System.out.println("非递归二分查找:"+result);//4
result = BinarySearch(arr,8,0,6);
System.out.println("递归二分查找:"+result);//6
Scanner scanner = new Scanner(System.in);
System.out.println("天数");
int day = scanner.nextInt();
System.out.println("糖果数");
int size = scanner.nextInt();
result = Search(day,size);
System.out.println(result);
}
来源:CSDN
作者:思〤行
链接:https://blog.csdn.net/qq_44682003/article/details/104718760