当一个有序数组中,有多个相同的数值时,如何利用二分查找将所有的数值都找到???
1.在找到mid时不要马上返回
2.可以向mid索引值的左边扫描,将满足等于val的值的下标加入到集合ArrayList中
3.可以向mid索引值的右边扫描,将满足等于val的值的下标加入到集合ArrayList中
4.返回ArrayList
代码实现如下:
package com.atguigu.serach;
import java.util.ArrayList;
import java.util.List;
public class BinarySearch {
public static void main(String[] args) {
int[] arr= {0,2,3,5,10,10,45,67,89,89};
List<Integer> list=dBinarySearch2(arr, 89);
System.out.println("使用递归实现二分查找多值的结果:"+list);
list=cirBinarySearch2(arr, 0, arr.length, 89);
System.out.println("使用递归实现二分查找多值的结果:"+list);
}
//迭代实现二分查找多值
public static List<Integer> dBinarySearch2(int[] arr,int val) {
int right=arr.length;//右索引
int left=0;//左索引
List<Integer> list=new ArrayList<Integer>();
while(left<right) {
int mid=(left+right)/2;
if(arr[mid]>val) {//要查找的数在左边,right左移
right=mid-1;
}
else if(arr[mid]<val) {//要查找的数在右边,left右移
left=mid+1;
}
else {
//向左扫描
int temp=mid-1;
while(temp>=0&&arr[temp]==val) {
list.add(temp);
temp--;
}
list.add(mid);
//向右扫描
temp=mid+1;
while(temp<arr.length&&arr[temp]==val) {
list.add(temp);
temp++;
}
return list;
}
}
return list;//查找到最后都没找到,直接返回null
}
//递归实现二分查找多值
public static List<Integer> cirBinarySearch2(int[] arr,int left,int right,int val) {
List<Integer> list=new ArrayList<>();
while(left<right) {
int mid=(left+right)/2;
if(arr[mid]==val) {
int temp=mid-1;
while(temp>=0&&arr[temp]==val) {
list.add(temp);
temp--;//temp左移
}
list.add(mid);
temp=mid+1;
while(temp<=arr.length-1&&arr[temp]==val) {
list.add(temp);
temp++;//temp右移
}
return list;
}
if(arr[mid]>val) {//要查找的数在左边,right左移
right=mid-1;
cirBinarySearch(arr, left, right, val);
}
else{//要查找的数在右边,left右移
left=mid+1;
cirBinarySearch(arr, left, right, val);
}
}
return list;//查找到最后都没找到,直接返回null
}
}
本文介绍了一种改进的二分查找算法,用于在有序数组中查找所有相同目标值的位置。通过向找到的中间值左右两侧扫描,可以收集所有目标值的索引,适用于有重复元素的数组查找。


被折叠的 条评论
为什么被折叠?



