给定一个按照升序排列的长度为 n的整数数组,以及 q 个查询。
对于每个查询,返回一个元素 kk 的起始位置和终止位置(位置从 0开始计数)。
如果数组中不存在该元素,则返回 -1 -1
。
输入格式
第一行包含整数 n 和 q,表示数组长度和询问个数。
第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。
接下来 q 行,每行包含一个整数 k,表示一个询问元素。
输出格式
共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回 -1 -1
。
数据范围
1≤n≤100000
1≤q≤100001
1≤k≤10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1
解题思路:
二分查找,其中待查找的元素不只出现一次,需要左右“探索”。
java代码:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] split = br.readLine().split(" ");
int n = Integer.parseInt(split[0]);
int q = Integer.parseInt(split[1]);
split = br.readLine().split(" ");
int []arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(split[i]);
}
StringBuilder ans = new StringBuilder();
for(int i = 0; i < q; i++) {
int des = Integer.parseInt(br.readLine());
ans.append(binarySearch(arr, des));
}
System.out.print(ans.toString().trim());
}
public static String binarySearch(int []arr, int des) {
int l = 0;//二分的最左端
int r = arr.length - 1;//最右端
while(l <= r) {//合法情况
int mid = (l + r) / 2;//二分的中间
if(arr[mid] > des) {//目的值小于中间值
r = mid - 1;//右端点左移
}else if(arr[mid] < des) {//目的值大于中间值
l = mid + 1;//左端点右移
}else {//已经找到目的值
int temp = mid - 1;//重复值的最左端
while(true) {
if(temp < 0 || arr[temp] != des)break;
temp--;
}
int tem = mid + 1;//重复值的最右端
while(true) {
if(tem > arr.length - 1 || arr[tem] != des) break;
tem++;
}
return (temp + 1) + " " + (tem - 1) + "\n";
}
}
return "-1 -1\n";
}
}