22、查找算法-二分法查找
来源:https://www.bilibili.com/video/BV1B4411H76f?p=77
一、思路
二分法:这里序列必须要有序
1、确定中间那个数值的下标,mid=(left+right)/2。假定序列是从小到大排列的。
2、目标值(finalVal)与中间的数值比较,
finalVal>arr[mid],向右递归。
finalVal<arr[mid],向左递归。
finalVal=arr[mid],找到了。
left>right,没找到
3、找到之后再向左向右查看一下,是否有相邻且相等的值。
二、实现
1 //二分法查找 2 public class BinarySearch { 3 public static void main(String[] args) { 4 int[] arr = {1,2,3,4,5,6,7,8,9,10}; 5 6 int a = binarySearch(arr,0,arr.length,8); 7 System.out.println(a); 8 } 9 10 public static int binarySearch(int[] arr,int left,int right,int finalVal){ 11 if(left > right){ 12 return -1; 13 } 14 int mid = (left + right) / 2; 15 int midVal = arr[mid]; 16 if(finalVal > midVal){ 17 return binarySearch(arr,mid+1,right,finalVal); 18 }else if(finalVal < midVal){ 19 return binarySearch(arr,left,mid-1,finalVal); 20 }else { 21 return mid; 22 } 23 } 24 25 }
结果
7
完善,增加向左向右查看的功能
1 public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int finalVal){ 2 if(left > right){ 3 return new ArrayList<Integer>(); 4 } 5 int mid = (left + right) / 2; 6 int midVal = arr[mid]; 7 if(finalVal > midVal){ 8 return binarySearch2(arr,mid+1,right,finalVal); 9 }else if(finalVal < midVal){ 10 return binarySearch2(arr,left,mid-1,finalVal); 11 }else { 12 ArrayList<Integer> resIndexList = new ArrayList<Integer>(); 13 //向左 14 int temp = mid - 1; 15 while (true){ 16 if(temp < 0 || arr[temp] != finalVal){ 17 //左边到头了,或者左边的没有相等的 18 break; 19 }else { 20 resIndexList.add(temp); 21 temp -= 1; 22 } 23 } 24 25 //当前 26 resIndexList.add(mid); 27 28 //向右 29 temp = mid + 1; 30 while (true){ 31 if(temp > arr.length - 1 || finalVal != arr[temp]){ 32 //右边到头了,或者右边的没有相等的 33 break; 34 }else { 35 resIndexList.add(temp); 36 temp += 1; 37 } 38 } 39 return resIndexList; 40 } 41 }
测试
1 int[] arr = {1,2,3,4,5,6,7,8,9,10,10,10,10}; 2 3 int a = binarySearch(arr,0,arr.length,8); 4 System.out.println(a); 5 6 ArrayList<Integer> b = binarySearch2(arr,0,arr.length,10); 7 System.out.println(b);
结果
7
[9, 10, 11, 12]