标签:ring contains 顺序 scan 结束 system 代码 tin 检查
为了不断优化推荐效果,今日头条每天要存储和处理海量数据。假设有这样一种场景:我们对用户按照它们的注册时间先后来标号,对于一类文章,每个用户都有不同的喜好值,我们会想知道某一段时间内注册的用户(标号相连的一批用户)中,有多少用户对这类文章喜好值为k。因为一些特殊的原因,不会出现一个查询的用户区间完全覆盖另一个查询的用户区间(不存在L1<=L2<=R2<=R1)。
输入: 第1行为n代表用户的个数 第2行为n个整数,第i个代表用户标号为i的用户对某类文章的喜好度 第3行为一个正整数q代表查询的组数 第4行到第(3+q)行,每行包含3个整数l,r,k代表一组查询,即标号为l<=i<=r的用户中对这类文章喜好值为k的用户的个数。 数据范围n <= 300000,q<=300000 k是整型
输出:一共q行,每行一个整数代表喜好值为k的用户的个数
5 1 2 3 3 5 3 1 2 1 2 4 5 3 5 3
1 0 2
样例解释: 有5个用户,喜好值为分别为1、2、3、3、5, 第一组询问对于标号[1,2]的用户喜好值为1的用户的个数是1 第二组询问对于标号[2,4]的用户喜好值为5的用户的个数是0 第三组询问对于标号[3,5]的用户喜好值为3的用户的个数是2
解答:
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
int num;
Scanner sc = new Scanner(System.in);
num=sc.nextInt(); //n个用户
int[] arr= new int[num];
for(int i=0;i<num;i++)
arr[i]=sc.nextInt(); //用户的喜好值
int leng= sc.nextInt(); //查询组数
int[] lrk= new int[3];
for(int i=0;i<leng;i++){
int temp=0;
for(int j=0;j<3;j++)
lrk[j]=sc.nextInt(); //l,r,k
for(int j=lrk[0]-1;j<lrk[1];j++){ //在l<=j<=r中,依次查找值为k的
if(arr[j]==lrk[2])
temp=temp+1;
}
System.out.println(temp);
}
}
}
运行结果:
运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大
case通过率为50.00%
然后呢,我就想到可能是代码的
for(int j=lrk[0]-1;j<lrk[1];j++){ //在i<=j<=r中,依次查找值为k的
if(arr[j]==lrk[2])
temp=temp+1;
}
运行时间过长了,然后试了改成二分查找。
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
int num;
Scanner sc = new Scanner(System.in);
num=sc.nextInt();
int[] arr= new int[num];
for(int i=0;i<num;i++)
arr[i]=sc.nextInt();
int leng= sc.nextInt();
int[] lrk= new int[3];
for(int i=0;i<leng;i++){
int temp=0,left=0,right=0,mid=0,target=0;
for(int j=0;j<3;j++)
lrk[j]=sc.nextInt();
left=lrk[0]-1;
right=lrk[1]-1;
target=lrk[2];
int[] sonarr = new int[right-left+1];
for(int j=0;j<right-left+1;j++)
sonarr[j]=arr[left+j];
Arrays.sort(sonarr); //对l-r间的数据排序,后续进行二分查找,若对整个arr排序,则是错误的,因为喜好值对应的人的id变了,对在[l,r]间数据排序则无影响,因为k值在这里面查找,顺序无影响
right=right-left;
left=0;
while(sonarr[left]<target&&sonarr[right]>target){
mid=(left+right)/2;
if(sonarr[left+1]==target||sonarr[right-1]==target)
break;
else if(sonarr[mid]<target)
left=mid;
else if(sonarr[mid]>target)
right=mid;
}
for(int j=left;j<=right;j++){
if(sonarr[j]==target)
temp=temp+1;
}
System.out.println(temp);
}
}
}
结果程序通过率为0.00%,(┬_┬)
啊,做了一个小时心态崩了,没办法,看看别人的吧.....看了一遍大佬的思路,然后自己又做了一遍..
思路就是,把喜好值(key)相同的人放在一个value里,比如(1,3,3,5,6,6,6),那么喜好值(key)为3的人有2,3,所以map里存放的数据为{(1,“1”),(3,“2,3”),(5,“4”),(6,“5,6,7”)}
然后通过k=key的方式,依次读取value中的值是否是 l<=value(i)<=r,若是,则temp+1。若没找到这个key,那么那么输出temp=0。
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
Scanner in =new Scanner(System.in);
int peo= in.nextInt();
int[] arr = new int[peo];
for(int i=0;i<peo;i++)
arr[i]=in.nextInt();
Map<Integer,ArrayList<Integer>> map = new HashMap();
ArrayList<Integer> list;
for(int i=0;i<peo;i++){
int key=arr[i];
int value=i+1;
list = new ArrayList<Integer>();
if(map.containsKey(key)){
list=map.get(key);
list.add(value);
}else {
list.add(value);
map.put(key,list);
}
}
int num=in.nextInt();
for(int i=0;i<num;i++){
int temp=0;
int l=in.nextInt();
int r=in.nextInt();
int k=in.nextInt();
list = new ArrayList<Integer>();
if(!map.containsKey(k))
System.out.println(temp);
else{
list=map.get(k);
for(int x:list){
if(l<=x&&x<=r)
temp=temp+1;
}
System.out.println(temp);
}
}
}
}
ACCEPT!!
标签:ring contains 顺序 scan 结束 system 代码 tin 检查
原文地址:https://www.cnblogs.com/zhuii/p/9951437.html