基本算法——二分法
程序员文章站
2023-12-27 08:28:21
...
目标:掌握整数二分和浮点二分,了解二分的思想
- AcWing789 数的范围 整数二分
- AcWing790 数的三次方根 浮点二分
这里我要反思之前写的两篇博客,感觉内容上自己思考的太少、而且细节上确实很多点没有讲到
以后会经量把自己的思路也加上去、希望大家能看的更加明白
整数二分
题目:
给定一个按照升序排列的长度为n的整数数组,以及 q 个查询。
对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。
如果数组中不存在该元素,则返回“-1 -1”。
比如:
举个例子:用题目中的找到起始位置和结束位置
总结,要让l= mid时,记得加一
题解
package Chapter1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* P789 数的范围
* @author vccyb
*
*/
public class P789 {
public static void main(String[] args) throws IOException {
//1. 输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] line1 = br.readLine().split(" ");
int n = Integer.parseInt(line1[0]);
int q = Integer.parseInt(line1[1]);
int[] arr = new int[n];
String[] line2 = br.readLine().split(" ");
for(int i=0;i<n;i++){
arr[i] = Integer.parseInt(line2[i]);
}
//2. 调用二分法
while(q-->0){
int target = Integer.parseInt(br.readLine());
if(bsearch(arr, 0, n-1, target)){
bsearch2(arr, 0, n-1, target);
}
System.out.println();
}
}
public static boolean bsearch(int[] arr, int l, int r, int target){
boolean flag = true;
//1. 找起始位置,由于是有序的,有相同的一定是靠左边
while(l < r){
int mid = l + r >> 1;
if(arr[mid]>=target){
r = mid;
}else{
l = mid + 1;
}
}
if(arr[l]!=target){
//找不到
flag = false;
System.out.print("-1 -1");
}else{
System.out.print(l + " ");
}
return flag;
}
//2. 找最大的终止位置
public static void bsearch2(int[] arr, int l, int r, int target){
while(l < r){
int mid = l + r + 1 >> 1;
if(arr[mid]<=target){
l = mid;
}else{
r = mid - 1;
}
}
System.out.print(l + " ");
}
}
模板
// 情况1
public static int bsearch(int[] arr, int l, int r){
while(l < r){
int mid = l + r >> 1;
if(check[mid]){
r = mid;
}else{
l = mid + 1;
}
}
return l;
}
//情况二
public static int bsearch(int[] arr, int l, int r){
while(l < r){
int mid = l + r + 1 >> 1; //很关键
if(check[mid]){
l = mid;
}else{
r = mid - 1;
}
}
return l;
}
浮点二分
浮点二分就更加简单了
一直分即可了
题目:
给定一个浮点数n,求它的三次方根。
题解
浮点二分条件可以是精度即可