二分不一定需要有序性,只需要确保二分的两边不同时满足某一性质即可。
目录
整数二分
整数二分会出现很多边界问题。
练习题目:二分查找
java题解
class Solution {
public int search(int[] nums, int target) {
// 二分查找
int right = nums.length - 1;
int left = 0;
while (left <= right) {
int mid = left + (right - left) / 2;
if (target < nums[mid])
right = mid - 1;// 注意right=mid-1
else if (target > nums[mid])
left = mid + 1;// 注意left=mid+1,而不是left=mid,不然会无限循环
else if (target == nums[mid]) {
return mid;
}
}
return -1;
}
}
练习题目:数的范围
java题解
import java.util.Scanner;
public abstract class Main {
public static void check(int[] nums, int number) {
int left = 0;
int right = nums.length - 1;
while (left < right) {// 查找这个数最右边出现的下标
int mid = (left + right) / 2;
if (nums[mid] >= number)
right = mid;
else
left = mid + 1;
}
if (nums[left] != number) {// 没有找到这个数
System.out.println("-1 -1");
return;
}
System.out.print(left + " ");
left = 0;// 初始化
right = nums.length - 1;
while (left < right) {// 查找这个数最左边出现的下标
int mid = (left + right + 1) / 2;
if (nums[mid] <= number)
left = mid;
else
right = mid - 1;
}
System.out.println(right);
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
int[] nums = new int[n];
for (int i = 0; i < n; i++) {// 接收数组
nums[i] = input.nextInt();
}
for (int i = 0; i < m; i++) {
int temp = input.nextInt();
check(nums, temp);// 输出结果
}
}
}
浮点二分
浮点二分不用考虑边界问题
练习题目:数的三次方根
java题解
import java.util.Scanner;
public abstract class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double n = input.nextDouble();
double left = -50, right = 50;
while (right - left > 1e-8) {//不用考虑边界问题,但是有浮点数有精度问题,精度应当高于要求保留的小数位
double mid = (left + right) / 2;
if (mid * mid * mid >= n)
right = mid;
else
left = mid;
}
System.out.printf("%.6f", left);
}
}