蓝桥杯试题 算法训练 区间k大数查询(Java)

试题 算法训练 区间k大数查询(Java)


方法:排序、查找

题目

资源限制

时间限制:1.0s
内存限制:256.0MB

问题描述

给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。

输入格式

第一行包含一个数n,表示序列长度。

第二行包含n个正整数,表示给定的序列。

第三个包含一个正整数m,表示询问个数。

接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。

输出格式

总共输出m行,每行一个数,表示询问的答案。

样例输入

5
1 2 3 4 5
2
1 5 2
2 3 2

样例输出

4
2

数据规模与约定

对于30%的数据,n,m<=100;
对于100%的数据,n,m<=1000;
保证k<=(r-l+1),序列中的数<=106。

分析:

一开始看到这道题的时候我还是不会的,最后思索了很久才发现,这个可以使用二维数组进行解决,然后就尝试了几次,然后接解决了这个事情,接下来我分享一下,我在做这道题的时候的一些分析思路,希望能够带给一些没有思路的朋友一些灵感。
1.第一步先利用一维数组int arr[ ] = new int [n]将数据录入。
2.再创建一个一维数组 int arr [ ] = new int [m],录入我们要寻找的第几大数字 k 。创建一个二维数组int arr1 [ ] [ ]= new int [m] [1000] ,然后,利用循环,将一维数组中的 l 到 r 的之间的这几位数字录入到二维数组中,输入的m是多少,就录入多少次,每次对应的数字和数目都是 l 和 r 对应的那些数字。
3.现在,我们已经创建了m 行,每列不一定相等的二维数组。现在对这个二维数组的每一行进行排列,调用方法Arrays.sort()进行排序,当然这个是从小到大排序的(因为我之前用了冒泡法和其他方法,结果失败了,然后就只能用这个方法,然后再反向调用,也可以正常输出),因为之前,我给这个二维数组创建了m行,1000列,在这1000列里面除了有效值外,其他的值都是默认值0,如果从小到大排列了之后,那前面都是0,从索引999往前数字逐渐减小。因此,利用循环,从后往前找这个第K大的数字,获取arrk[i]里面的数值,来寻找这个数字,如果是第一大数字,那就是输出的是arr[i] [999],第二大数字,就是arr1[i] [998],这样我们通过分析,可以知道,这个最终的数字就是1000-k,即就是1000-arrk[i]。
4.最后,输出结果,完成了这道题。

代码如下:
import java.util.Scanner;
import java.util.Arrays;
class Main{
	public static void main(String [] args){
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int arr[] = new int [n];
		for (int i = 0 ; i < arr.length; i ++){
			arr[i] = sc.nextInt();
		}
		int m = sc.nextInt();
		
		int arrk[] = new int [m];
		int arr1[][] = new int[m][1000];
		for(int i = 0; i < m; i ++){
			int l = sc.nextInt();
			int r = sc.nextInt();
			int k = sc.nextInt();
			int temp = 0;
			for(int j = l-1; j < r; j++){				
					arr1[i][temp++] = arr[j];
			}		
			arrk[i]= k;
		}
		for(int i = 0; i < m ; i ++){
			for(int j = 0; j < arr1[i].length; j++){
				arr1[i][j] = arr1[i][j];
			}
		}		
		int te = 0;
		for(int i = 0 ; i < m ; i ++){
			Arrays.sort(arr1[i]);
		}
				
		for(int i = 0;i < m ; i ++){
			int z = arrk[i] ;
			int y = 1000 -z;
			System.out.println(arr1[i][y]);
		}
		
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李长欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值