0
点赞
收藏
分享

微信扫一扫

789. 数的范围 java 题解 (二分)

爱喝酒的幸福人 2022-02-07 阅读 68

给定一个按照升序排列的长度为 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";
	}
}
举报

相关推荐

0 条评论