二分算法
二分法
时间复杂度:logN
1)在一个有序数组中,找某个数是否存在
package day1;
import java.util.Arrays;
/*
* 二分查找其中精确的一个数
*/
public class Code4_BSExist {
public static boolean exist(int[] sortedArr,int num) {
if(sortedArr == null || sortedArr.length == 0) return false;
int L = 0;
int R = sortedArr.length - 1;
int mid = 0;
while(L < R) {
//mid = (L +R) / 2
mid = L+((R-L) >> 1); // mid = (L+R)/2
if(sortedArr[mid] == num) {
return true;
} else if (sortedArr[mid] > num) {
R = mid- 1;
} else {
L = mid + 1;
}
}
return sortedArr[L] == num;
}
public static int[] generateRandomArray(int maxSize,int maxValue) {
//Math.random() [0,1)
//Math.random() * N [0,N)
//(int)(Math.random()*N) [0,N-1]
int[] arr = new int[(int)(Math.random()*(maxSize+1))];
for(int i = 0 ; i < arr.length; i++) {
//想做到负的到整的都有
arr[i] = (int)((maxValue+1)*Math.random()) - (int)((maxValue+1)*Math.random());
}
return arr;
}
public static void main(String[] args) {
int[] arr = generateRandomArray(100,100);
int t = (int)((100+1)*Math.random()) - (int)((100+1)*Math.random());
boolean res = exist(arr,t);
System.out.println(Arrays.toString(arr));
System.out.println(t);
System.out.println(res);
}
}
2)在一个有序数组中,找>=某个数最左侧的位置
package day1;
//在arr上,找满足>=value的最左位置
public class Code5_BSBearLeft {
public static int nearestIndex(int[] arr,int value) {
int L = 0;
int R = arr.length -1;
int index = -1; //记录最左的对号
while(L <= R) {
int mid = L + ((R-L) >> 1 );
if(arr[mid] >= value) {
index = mid;
R = mid - 1;
} else {
L = mid +1;
}
}
return index;
}
}
3)在一个有序数组中,找<=某个数最右侧的位置
package day1;
////在arr上,找满足<=value的最左位置
public class Code6_BSBearRight {
public static int nearestIndex(int[] arr,int value) {
int L = 0;
int R = arr.length -1;
int index = -1; //记录最右的对号
while(L <= R) {
int mid = L + ((R-L) >> 1 );
if(arr[mid] <= value) {
index = mid;
R = mid - 1;
} else {
L = mid +1;
}
}
return index;
}
}
4)局部最小值问题
0位置比1位置小
n位置比n-1位置小
n位置比n-1位置,n+1位置小
package day1;
//局部最小值问题
public class Code7_BSAwesome {
public static int getLessIndex(int[] arr) {
if(arr == null || arr.length == 0) return -1;
if(arr.length == 1 || arr[0] < arr[1]) return 0;
if(arr[arr.length-1] < arr[arr.length -2]) return arr.length-1;
int left = 1;
int right = arr.length - 2;
int mid = 0;
while(left < right) {
mid = (left +right) >> 1;
if(arr[mid] > arr[mid-1]) {
right = mid-1;
} else if(arr[mid] > arr[mid+1]) {
left = mid +1;
} else
return mid;
}
return left;
}
}