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;//表示没找到
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?