试题 算法训练 预备爷的悲剧 java的实现

问题描述
  英语预备爷gzp是个逗(tu)比(hao),为了在即将到来的英语的quiz中不挂科,gzp废寝忘食复习英语附录单词表,俨然一场人间悲剧。不过上天有好生之德,上帝扔给了gzp一张纸,上面记载了将要考到的单词。不过gzp是个逗比,之前复习的东西全忘记了,所以他又要再来一次复习。不过已经知道了要考的单词,所以不需要复习单词表的所有页数。因此,现在需要你帮助他求出有多少页纸需要复习。他会告诉你每个单词会在哪几页出现,并且告诉你要考哪些单词,你只要告诉他答案就可以了。由于一个单词会出现在不同页上,只需要复习在最前面一页上的就可以了。
输入格式
  第一行一个整数n,表示单词附录有n个单词。接下来n行每行一个小写字母组成的单词和一个整数,表示某一个单词和它所在的页数。接下来是一行整数m,表示要考m个单词,接下来m行小写字母组成的单词,表示要考到的单词。
输出格式
  一个数,表示需要复习的页数。
样例输入
5
ab 1
ac 2
ab 2
ac 3
c 3
3
ab
ac
c
样例输出
3
数据规模和约定
  0<=n,m<=100000,单词长度<=10。
————————————————————————————————————————
解题思路:先给到单词和对应页数,可以联想到Key-Value,也就是用Map来存储,其中题目告诉我们,会出现相同的单词,只复习最前面一页的就行,给的页数据不会从小到大给的,所以存储相同单词时,比较一下页码大小,存储后,再给我们要复习的单词,用key去Map里面拿数据就好了,此时有些单词在同一页怎么办呢?我们用Set集合去收集复习单词的页数,Set不会存储重复的数据,最终输出Set的大小就可以了。


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		Reader reader = new Reader();
		reader.init(System.in);
		int n = reader.nextInt();
		Map<String, Integer> map = new HashMap<String, Integer>();
		for (int i = 0; i < n; i++) {
			String word = reader.next();//读取单词
			int page = reader.nextInt();//读取单词对应的页码
			int page2 = map.getOrDefault(word, Integer.MAX_VALUE);//查询Map里面有没有该单词,没有默认Integer最大值
			if (page2 > page) {//保存页码小的
				map.put(word, page);
			}
		}
		Set<Integer> set = new HashSet<>();//用Set存储要复习的页码
		int m = reader.nextInt();
		for (int i = 0; i < m; i++) {
			String str = reader.next();//读取要复习的单词
			Integer page = map.get(str);//从Map里面获取页码
			set.add(page);//存到Set集合中,重复的页码 Set只会存储一次
		}
		System.out.println(set.size());//输出Set的大小即要复习的页数
	}

}
//读取数据的工具类
class Reader {
	BufferedReader reader;
	StringTokenizer tokenizer;

	/** call thReader method to initialize reader for InputStream */
	void init(InputStream input) {
		reader = new BufferedReader(new InputStreamReader(input));
		tokenizer = new StringTokenizer("");
	}

	/** get next word */
	String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			// TODO add check for eof if necessary
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
}

题目数据量比较大,一开始我用List存储页码,List.contains()方法检测是否存在页码,存在则不存储该页码,估摸这样的效率比Set低,还有用Scanner读取数据的效率也比较低,导致提交结果有运行超时的,而且通过的点的运行时间也很久。
在这里插入图片描述
于是想到用BufferedReader来读取数据,利用别人以及写好的Reader工具类(比较懒,嘿嘿),List改成Set,修改修改代码提交,芜湖~快很多。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值