- 基础应用:在有序数组中找指定num
public class test1 {
public static int sort(int[]arr,int num){
if(arr==null||arr.length==0){
return -1;
}
int L=0;
int R=arr.length-1;
while(L<=R){
int mid=(R+L)/2;
if(arr[mid]==num){
return mid;
}else if(arr[mid]<num){
L=mid+1;
}else if(arr[mid]>num){
R=mid-1;
}
}
return -1;
}
public static void main(String[] args) {
int[]arr={1,3,4,5,6,8,9,14,17,31};
int a=sort(arr,1);
System.out.println(a);
}
}
-
在有序数组中查找>=num的最左的位置【为了确定最左位置,会把整个数组切完】
public static int mostLeft(int[]arr,int num){
//保证arr有序
if(arr==null||arr.length==0){
return -1;
}
int L=0;
int R=arr.length-1;
//设置指针
int ans=-1;
while(L<=R){
int mid=(R+L)/2;
if(arr[mid]>=num){
R=mid-1;
ans=mid;
}else{
L=mid+1;
}
return ans;
}
-
局部最小值问题:无序数组中任意两个相邻位置不相等,局部最小比它相邻两数都小
-
二分法不一定需要有序:
-
如果arr[0]不是局部最小,说明arr[0]>arr[1] 【下降趋势】,又如果arr[N-1]不是局部最小,说明arr[N-2]>arr[N-1] 【上升趋势】,则arr[0]-arr[N-1]一定存在局部最小
-
如果arr[mid]不是局部最小,说明arr[mid]>arr[mid-1] 或arr[mid+]【下降趋势】,则arr[0]-arr[mid]或arr[mid]-arr[N-1]一定存在局部最小
-
-
public class test2 {
//二分法找局部最小
public static int findMin(int[] arr){
int N = arr.length;
int ans=-1;
//如果为空,直接返回-1
if(arr==null || N==0){
return ans;
}
//如果数组长度为1,返回本身
if(N==1){
ans=arr[0];
return ans;
}
//如果数组长度为2,返回最小数
if(N==2){
ans=arr[0]<arr[1]?arr[0]:arr[1];
return ans;
}
//如果数组长度大于2
int L=0;
int R=N-1;
//L到R肯定有局部最小,用二分法寻找
while(L<R-1){
int mid=(L+R)/2;
//mid就是局部最小,小于其两边数
if(arr[mid]<arr[mid-1]&&arr[mid]<arr[mid+1]){
ans=mid;
return ans;
}else {
//缩小范围
if(arr[mid]>arr[mid-1]){
R=mid-1;
}else if(arr[mid]>arr[mid+1]){
L=mid+1;
}
}
}
//到最后只剩L和R,L=R-1
return arr[L]<arr[R]?L:R;
}
//生成随机数组用于测试
public static int[] RandomArr(int maxlength,int maxValue){
//生成长度不超过maxlength随机长度数组
int len=(int)(Math.random()*maxlength);
int[] arr=new int[len];
if(len>0){
// 随机生成数值不超过maxvalue的arr[0]
arr[0]=(int)(Math.random()*maxValue);
//确保arr[i]!=arr[i+1}
for (int i = 1; i <len ; i++) {
do{
arr[i]=(int)(Math.random()*maxValue);
}while(arr[i]==arr[i-1]);
}
}
return arr;
}
//用随机数组测试查找方法是否正确
public static boolean check(int[]arr,int minIndex){
if(arr.length==0){
return minIndex==-1;
}
if(arr.length==1){
return minIndex==0;
}
int left = minIndex - 1;
int right = minIndex + 1;
boolean leftBigger = left >= 0 ? arr[left] > arr[minIndex] : true;
boolean rightBigger = right < arr.length ? arr[right] > arr[minIndex] : true;
return leftBigger && rightBigger;
}
public static void main(String[] args) {
int maxlength=100;
int maxValue=1000;
int[] arrs =RandomArr(maxlength, maxValue);
int min = findMin(arrs);
boolean check = check(arrs, min);
System.out.println(check);
}
}