public class TwoDepartFind {
public static void main(String[] args) {
//二分法查找思路:
//在一个有序数组里查找是否存在某个值,方式先比较下标为array[midIndex]
int[] array = {3,5,12,20,300,300,300,800,1000};
int midIndex = array.length/2;
int finalVal = 300;//待查找的数值
int left = 0;
int right = array.length-1;
int res = getFinalIndex( array, left, right, finalVal);
System.out.println("下标为:"+res);
int countAll = 0;
int res2 = getFinalCount( array, left, right, finalVal,0);
System.out.println("总共有:"+res2);
}
//临界值判断什么时候二分法没办法继续下去
//当left==right应该是最后一次二分,如果这次找不到就说明没找到,此时下标移动将导致left> right,打破了算法边界
public static int getFinalIndex(int[] array,int left,int right,int finalVal)
{
if(left>right){
return -1;//表示没找到
}
int midIndex = (right+left)/2;
if(finalVal<array[midIndex] ){
right = midIndex -1;
return getFinalIndex(array,left,right,finalVal);
}else if(finalVal>array[midIndex]){
left = midIndex +1;
return getFinalIndex(array,left,right,finalVal);
}else {
return midIndex;//表示找到了
}
}
///
//查找有多少个,查找的思路是一样的,只不过现在找到了还要继续找
/**
* @Description: 创建对应查找计数的方法
* @Param: [int[], int, int, int]
* @return: int
* @Author: 张友东
* @Date: 2021/9/10
*/
public static int getFinalCount(int[] array,int left,int right,int finalVal,int countAll)
{
if(left>right){
return -1;//表示没找到
}
int midIndex = (right+left)/2;
if(finalVal<array[midIndex] ){
right = midIndex -1;
return getFinalIndex(array,left,right,finalVal);
}else if(finalVal>array[midIndex]){
left = midIndex +1;
return getFinalIndex(array,left,right,finalVal);
}else {
countAll++;
//找到之后继续找,因为是有序队列,如果存在多个finalVal,在数组中的位置一定相邻
//还是分成往前找和往后找
int temp1 = midIndex-1;
while(true){
//如果相邻元素前一个不等于finalVal
if(temp1 < 0 || array[temp1] != finalVal){
break;
}else{
countAll++;
//如果找到了继续往前找
temp1 +=temp1;
}
}
//往后找
int temp2 = midIndex+1;
while(true){
//如果相邻元素前一个不等于finalVal
if(temp2>array.length-1 || array[temp2] != finalVal){
break;
}else{
countAll++;
//如果找到了继续往后找
temp2+=1;
}
}
return countAll;//表示没找到
}
}