题解:AcWing 789. 数的范围 JAVA

题目描述

给定一个按照升序排列的长度为n的整数数组,以及 q 个查询。
对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。
如果数组中不存在该元素,则返回“-1 -1”。
输入格式
第一行包含整数n和q,表示数组长度和询问个数。
第二行包含n个整数(均在1~10000范围内),表示完整数组。
接下来q行,每行包含一个整数k,表示一个询问元素。
输出格式
共q行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回“-1 -1”。
数据范围
1≤n≤100000
1≤n≤100000

1≤q≤10000
1≤q≤10000

1≤k≤10000
1≤k≤10000

样例
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1

优化二分查找跳过重复元素

此题采用正常的二分查找会超时,但我们可以注意到,此题有很多重复的数字例如(111223333)
我们二分查找时左边查找到第一个1的时候就可以跳过其余的1
可以通过一个数组来实现记录重复数字的个数,在二分查找时可以直接跳过

java代码
package 蓝桥;

import java.util.Scanner;
/******
 * 
 * @author genji
 * 此题采用正常的二分查找会超时,但我们可以注意到,此题有很多重复的数字例如(111223333)
 * 我们二分查找时左边查找到第一个1的时候就可以跳过其余的1
 * 可以通过一个数组来实现记录重复数字的个数,在二分查找时可以直接跳过
 */
public class 数的范围_789 {
	
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt(),m=scanner.nextInt();
		int[] a=new int[n];
		int[] b=new int[n];//b中存放重复数字的数量,因为下面采用二分查找所以有前后两个标志
		//例如a 中的数为1,1,1,1,1,2,2,2,2,3,3,4,4,4,4,5
		//则b中的数为      5,0,0,0,5,4,0,0,4,2,2,4,0,0,4,1
		//使其在查找时跳过重复的数字
		int c=0,i;
		for (i = 0; i < n; i++) {
			a[i]=scanner.nextInt();
			if (i==0||a[i]==a[i-1]) {
				c++;				//如果是第一个数或者和前面数字相同的数则记录相同数字的个数
			}
			else if (a[i]!=a[i-1]) {
				b[i-1]=c;
				b[i-c]=c;			//将相同数字个数赋到b数组相同下标的头和尾
				c=1;
			}
		}
		b[i-1]=c;
		b[i-c]=c;
		for (i = 0; i < b.length; i++) {
			System.out.println(b[i]);
		}
		while (m-->0) {
			int l=0,r=n-1;
			int q=scanner.nextInt();
			while (l<r) {
				
				if (a[l]!=q) {
					
					l+=b[l];//   跳过重复的数字
				}
				if (a[r]!=q) {
					r-=b[r];//   跳过重复的数字
				}
				if (a[r]==q&&a[l]==q) {
					
					System.out.println(l+" "+r);
					break;
				}
			}
			if(a[l]!=q&&a[r]!=q)
			{
				System.out.println(-1+" "+-1);
			}
			
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值