二分查找(BinarySearch)基本思想
参与二分查找的数据必须是有序的,不然没法进行。假设要查找的数为key。先找到查找的数据的中间值midValue,用key和中间值比较,如果key==midValue,就返回整个中间值的小标;如果不相等,分两种情况:①key<midVlaue,就继续递归查找midValue左边的数据 ②key>midVlaue,就继续递归查找midValue右边的数据
代码实现
public class BinarySearch {
public static void main(String[] args) {
int[] nums = {1, 5, 8, 90, 100, 100, 100, 101, 130, 188, 190};
System.out.println(binarySerachAll(nums, 100, 0, nums.length - 1));
}
/**
* 递归实现二分查找
*
* @param nums
* @param key
* @param left
* @param right
* @return
*/
public static int binarySerach(int[] nums, int key, int left, int right) {
if (left > right) {
return -1;
}
// 中间值的下标
int mid = (left + right) / 2;
int midValue = nums[mid];
if (midValue < key) {
// 查找右边的
return binarySerach(nums, key, mid + 1, right);
} else if (midValue > key) {
// 查找左边的
return binarySerach(nums, key, left, mid - 1);
} else {
// 找到目标值
return mid;
}
}
/**
* 迭代实现二分查找
*
* @param nums
* @param key
* @param left
* @param right
* @return
*/
public static int binarySerach2(int[] nums, int key, int left, int right) {
while (left <= right) {
int mid = (left + right) / 2;
if (key == nums[mid]) {
return mid;
} else if (nums[mid] < key) {
left = mid + 1;
} else if (nums[mid] > key) {
right = mid - 1;
}
}
return -1;
}
/**
* 如果有多个值满足条件,全部找出来
*
* @param nums
* @param key
* @param left
* @param right
* @return
*/
public static List<Integer> binarySerachAll(int[] nums, int key, int left, int right) {
if (left > right) {
return null;
}
int mid = (left + right) / 2;
int midValue = nums[mid];
if (midValue < key) {
return binarySerachAll(nums, key, mid + 1, right);
} else if (midValue > key) {
return binarySerachAll(nums, key, left, mid - 1);
} else {
ArrayList<Integer> arrayList = new ArrayList<>();
int temp = mid - 1;
// 查找mid左边有没有和key相等的
while (nums[temp] == key) {
arrayList.add(temp);
temp--;
}
arrayList.add(mid);
temp = mid + 1;
// 查找mid右边有没有和key相等的
while (nums[temp] == key) {
arrayList.add(temp);
temp++;
}
return arrayList;
}
}
}