本人技术小白一枚,文章只是记录个人的解题思路和过程

牛客网地址:原题链接

第一题:用户喜好

题目

为了不断优化推荐效果,今日头条每天要存储和处理海量数据。假设有这样一种场景:我们对用户按照它们的注册时间先后来标号,对于一类文章,每个用户都有不同的喜好值,我们会想知道某一段时间内注册的用户(标号相连的一批用户)中,有多少用户对这类文章喜好值为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

分析

一看题目,最先想到的就是枚举遍历:
将所有的用户喜好度k值保存在数组arr[]中,然后遍历查询的区间[l , r],判断是否喜好值是否是k。
不过看一下数据范围:n<=300000,q<=300000,直接遍历的方法时间复杂度是 O(nq),很明显是无法通过所有测试用例的。

这个时候我们必须换一种思路了,再分析一下题目,我们可以发现,除了可以使用用户序列号来获取喜好值k,我们同样可以通过喜好值k来反向获取用户的序列号列表,即将k作为key值,value为用户序列号列表List;key-value的存储方式,很明显,选用的集合类是HashMap;

想明白这一点,这道题就不难了,直接通过查询的k值来判断是否存在用户集合List,并遍历集合List,在[l, r]区间内即符合条件。

代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while(scanner.hasNext()) {int n = scanner.nextInt();int[] a = new int[n];for (int i = 0; i < n; i++) {a[i] = scanner.nextInt();}Map<Integer, List<Integer>> map = new HashMap<>();for (int i = 0; i < n; i++) {int key = a[i];if (map.containsKey(key)) {List<Integer> list = map.get(key);list.add(i+1);}else {List<Integer> list = new ArrayList<>();list.add(i+1);map.put(key, list);}}int q = scanner.nextInt();while((q--) > 0) {int l = scanner.nextInt();int r = scanner.nextInt();int k = scanner.nextInt();int count = 0;List<Integer> list = map.get(k);if (list != null) {for(Integer integer : list) {if (integer >= l && integer <= r) {count++;}}}System.out.println(count);}}}}

第二题:手串

题目:

作为一个手串艺人,有金主向你订购了一条包含n个杂色串珠的手串——每个串珠要么无色,要么涂了若干种颜色。为了使手串的色彩看起来不那么单调,金主要求,手串上的任意一种颜色(不包含无色),在任意连续的m个串珠里至多出现一次(注意这里手串是一个环形)。手串上的颜色一共有c种。现在按顺时针序告诉你n个串珠的手串上,每个串珠用所包含的颜色分别有哪些。请你判断该手串上有多少种颜色不符合要求。即询问有多少种颜色在任意连续m个串珠中出现了至少两次。

输入描述:

第一行输入n,m,c三个数,用空格隔开。(1 <= n <= 10000, 1 <= m <= 1000, 1 <= c <= 50) 接下来n行每行的第一个数num_i(0 <= num_i <= c)表示第i颗珠子有多少种颜色。接下来依次读入num_i个数字,每个数字x表示第i颗柱子上包含第x种颜色(1 <= x <= c)

输出描述:

一个非负整数,表示该手链上有多少种颜色不符需求。

输入例子:

5 2 3
3 1 2 3
0
2 2 3
1 2
1 3

输出例子:

2

分析

这道题同样可以使用和第一题一样的方法,用颜色c做key值,value是串珠标号列表List;

m个连续串珠内不能一种颜色出现两次,记录不合格的颜色数量,就变成了获取每种颜色的串珠标号列表List,判断List中相邻的两个数之间的差值是否大于m。

需要注意的是,因为珠串是一个环状结构,所以List中最后一个元素需要单独判断。

代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;public class Main2 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while(scanner.hasNext()) {int n = scanner.nextInt();int m = scanner.nextInt();int c = scanner.nextInt();Map<Integer, List<Integer>> map = new HashMap<>();for(int i=0; i<n; i++) {int num = scanner.nextInt();for(int j=0; j<num; j++) {int key = scanner.nextInt();if (map.containsKey(key)) {List<Integer> list = map.get(key);list.add(i);}else {List<Integer> list = new ArrayList<>();list.add(i);map.put(key, list);}}}int count = 0;Boolean flag;for (int i = 1; i <= c; i++) {flag = false;List<Integer> list = map.get(i);if (list != null) {Collections.sort(list);int j;for (j = 0; j < list.size()-1; j++) {int left = list.get(j);int right = list.get(j+1);if (left + m > right) {count++;flag = true;break;}}if (!flag && (j > 0) && ((list.get(j) + m) % n) > list.get(0)) {count++;}}}System.out.println(count);}}}

第三题:字母交换

题目:

字符串S由小写字母构成,长度为n。定义一种操作,每次都可以挑选字符串中任意的两个相邻字母进行交换。询问在至多交换m次之后,字符串中最多有多少个连续的位置上的字母相同?

输入描述:

第一行为一个字符串S与一个非负整数m。(1 <= |S| <= 1000, 1 <= m <= 1000000)

输出描述:

一个非负整数,表示操作之后,连续最长的相同字母数量。

输入例子:

abcbaa 2

输出例子:

2

分析

要求移动后形成最长连续相同字母子串,这个最长连续子串可能是a或b……z中的任意一个字母,很明显,可以把每个字母单独拆分出来,作为一个整体考虑,最后的结果比较每个字母得到的最长子串的长度,选取最大的即可。

首先就是遍历这个字符串的所有字符,使用字母的顺序值作为key值,把同一字母的位置,保存在一个List中,List作为一个序列从小到大排列。

接下来就是求解连续最长子序列的问题了,并且操作的次数还不能超过m,因此我们可以使用动态规划,先从小到大枚举段长,依次求得该段长的所有子序列的操作次数,并判断是否小于等于m,如果满足要求,就更新答案。

注:这道题的思路是我参考别的大神的
原文地址:
https://blog.csdn.net/flushhip/article/details/79416715

代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;public class Main3 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while(scanner.hasNext()) {String string = scanner.next();int m = scanner.nextInt();char[] cs = string.toCharArray();Map<Integer, List<Integer>> map = new HashMap<>();for (int i = 0; i < cs.length; i++) {int key = cs[i] - 'a';if (map.containsKey(key)) {List<Integer> list = map.get(key);list.add(i);}else {List<Integer> list = new ArrayList<>();list.add(i);map.put(key, list);}}int count = 0;for(int i=0;i<26;i++) {List<Integer> list = map.get(i);if (list != null) {int[][] dp = new int[list.size()][list.size()];//len指连续子串长度for(int len=2;len<=list.size();len++) {//j指子串起始位置,(j + len -1)指子串结束位置,//dp[j][j+len-1]指在j~(j+len-1)这段子串移动成连续子串所需要的次数for (int j = 0; j + len - 1 < list.size(); j ++) {/*dp[j+1][j+len-2]指将(j+1)~(j+len-2)之间的目标字母移动到一起,这个移动次数就是dp[i + 1][i + len - 2];然后将两个端点的字母向中间移,移动的距离就为(list.get(j+len-1) - list.get(j)) - (len-1)*/dp[j][j+len-1] = dp[j+1][j+len-2] + list.get(j+len-1) - list.get(j) + 1 -len; if (dp[j][j+len-1] <= m && count < len) {count = len;}}}}}System.out.println(count);}}}

今日头条2018校园招聘后端开发工程师(第二批)编程题 (Java版)相关推荐

  1. 今日头条2018校园招聘后端开发工程师(第二批)编程题 - 题解

    以前做过第三批的题目,今日头条2018校园招聘后端开发工程师(第三批)编程题 - 题解.这一场的题目偏技巧和算法,而第三批的题偏编码.这一场涉及的算法有二分查找.区间动态规划. 原题链接:点这儿. 第 ...

  2. 今日头条2018校园招聘后端开发工程师 (第二批) 编程题 - 字母交换

    题目描述: [编码题]字符串S由小写字母构成,长度为n.定义一种操作,每次都可以挑选字符串中任意的两个相邻字母进行交换.询问在至多交换m次之后,字符串中最多有多少个连续的位置上的字母相同? 输入描述: ...

  3. 今日头条2018校园招聘后端开发工程师(第四批)编程题 - 题解

    做过第三批的题目,今日头条2018校园招聘后端开发工程师(第三批)编程题 - 题解和第二批的题目,今日头条2018校园招聘后端开发工程师(第二批)编程题 - 题解. 这一场题目还是挺好玩的,也挺有技巧 ...

  4. 今日头条2018校园招聘后端开发工程师(第三批)编程题 - 题解

    昨天做了下头条的后端开发工程师的编程题,这编码量大啊,两个小时,三个编程题,一个改错题,一个设计题,说实话,很考技术含量,而且编程题中有两个还特别考细心编码,如果两个小时能做三个题,确实非常不错了,写 ...

  5. 手串(暴力) - 今日头条2018校园招聘后端方向(9.10)

    时间限制:1秒 空间限制:65536K 题目描述 作为一个手串艺人,有金主向你订购了一条包含n个杂色串珠的手串--每个串珠要么无色,要么涂了若干种颜色.为了使手串的色彩看起来不那么单调,金主要求,手串 ...

  6. 七牛2018春季校园招聘后端开发工程师笔试经验

    笔试公司:上海七牛信息技术有限公司 笔试岗位:后端开发工程师 笔试时间:2018年4月14日14:00-15:30 笔试形式:牛客网在线做题 笔试回忆: 笔试共分为不定项选择和问答两部分,不定项选择1 ...

  7. 今日头条2018校园招聘第一题 ---POJ 2479

    第一次参加公司的招聘笔试,虽然只是抱着试试水的心态去参加的,可惜的是第一题就做错了..... 第一题,其实只是一个求最大子段和的变式题,不过笔试的时候也不知道怎么了,就是不知道思路,最后还写了一个错的 ...

  8. 今日头条2018校园招聘第一次笔试第二题“字符串拼接”题解(一维动态规划及递归解法)

    3.24晚的笔试,结束后题目看不到了,有人截图了,来源:https://www.jianshu.com/p/00d3fd1d9e23 最新更新:在leetcode 上有一道类似的题,区别在于第一种操作 ...

  9. 今日头条2018校园春季招聘研发岗位笔试(第一场)经验

    笔试公司:今日头条 笔试岗位:后端开发 笔试时间:2018年3月24日19:00-21:00 笔试形式:牛客网在线做题 笔试回忆: 笔试总共五道题.是的,只有五道编码题,没有选择or填空. 第一题,输 ...

最新文章

  1. 1.MySQL基本体系
  2. 看图说话:OpenGL模型矩阵和投影矩阵
  3. 045_CSS3过渡
  4. 5、JUC--实现 Callable 接口
  5. hive sql 怎么实现循环_python怎么实现循环
  6. signature=78718ebfda6f8d955fae3e9c9c284f5d,SKI SAFETY BINDING WITH SWIVELLING SOLE PLATE
  7. 单元测试(Unit Test)学习
  8. python生成随机骨料模型代码_Abaqus Python脚本-3D随机球形骨料的生成
  9. jasmine.spy对象的and.returnValue方法单步调试
  10. Map<String,Object>接收参数,Long类型降级为Integer,报类型转换异常
  11. 基于Python的HTTP接口测试
  12. 生物流体力学及血流动力学建模仿真技术实战
  13. 基于Cassandra的分布式存储数据一致性算法研究
  14. 软件项目风险评估报告
  15. 蓝牙运动手环app开发方案
  16. LabVIEW编程LabVIEW开发Fluke8858A/8588A万用表 例程与相关资料
  17. mysql查询同名同姓重名人数,查询与自己同名的人,如何查找重名人数
  18. jersey 简单使用
  19. 【蜂口 | AI人工智能】人脸美颜——龙鹏 深度学习与人脸图像应用连载(八)...
  20. Vscode设置用户代码片段

热门文章

  1. java jmail_Java jmail邮件发送与不重复随机码 | 彬菌
  2. mac iphone 备份_PC或Mac上我的iPhone或iPad备份在哪里?
  3. 9行Python代码去除图片中的数字水印
  4. 如何写一个游戏AI(三)0-9手写数字图片识别AI训练
  5. 分享一个开源的古诗词数据库(约7w+古诗词/3k+诗人)
  6. 10年运营老兵,教你召回流失用户
  7. hdu2897邂逅明下——博弈sg函数的应用
  8. android 清理内存图标掉进垃圾桶的动画,垃圾桶 icon 小动效
  9. Android仿淘宝历史搜索功能,使用localStorage实现历史记录搜索功能也便是天猫app历史记录存储方便浏览...
  10. 过家家装修网php,过家家装修网