可以查找重复相同的数
package com.atguigu.search;
import java.util.ArrayList;
import java.util.List;
/**
* 二分查找法
* @author Dxkstart
* @create 2021-10-13-14:57
*/
public class BinarySearch {
public static void main(String[] args) {
//注意:使用二分查找的前提是,该数组是有序的。
int[] arr = {1,8,10,89,1000,1000,1000,1000,1234};
List<Integer> list = binarySearch2(arr, 0, arr.length - 1, 1000);
System.out.println(list);
}
/*
{1,8, 10, 89, 1000, 1000,1000,1234}
当一个有序数组中,有多个相同的数值时,
如何将所有的数值都查找到,比如这里的 1000.
思路分析:
1.在找到 mid 索引值,不要马上返回
2.向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
3.向mid 索引值的右边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
4.将ArrayList返回
*/
//完善二分查找
public static List<Integer> binarySearch2(int[] arr,int left,int right,int findVal){
//当left > right 时,说明递归整个数组,但是没有找到
if (left > right){
return new ArrayList<Integer>();
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (findVal > midVal){//需要向右递归
return binarySearch2(arr,mid + 1,right,findVal);
}else if (findVal < midVal){//需要向左递归
return binarySearch2(arr,left,mid - 1,findVal);
}else {//找到了
List<Integer> resIndexList = new ArrayList<>();
resIndexList.add(mid);//先将找到结果的放入集合中
//向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
int temp = mid - 1;
while (true){
if (temp < 0 || arr[temp] != findVal){
break;
}else {
//否则就将temp当入到resIndexList中
resIndexList.add(temp);
temp--;
}
}
//向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
temp = mid + 1;
while (true){
if (temp > arr.length - 1 || arr[temp] != findVal){
break;
}else {
resIndexList.add(temp);
temp++;
}
}
return resIndexList;
}
}
}