在昨天参加了东哥的笔试,选择题做的还算可以,但是还有道编程题和关于jdk8的Stream特性难住了。鉴于此用博客总结一下这道编程题,并结合Stream特性来简化代码,熟悉Api。

题目描述

某校在积极推行无人监考制度,但是总有学生是不自觉的,如果将两个很熟的异性朋友放在同一个考场里,他们就会交流甚至作弊。因此一个考场中不能允许两个很熟的异性朋友存在,学校希望通过搬出一部分学生的方法来改善这一问题。但是又因为教室数量有限,因此希望一个教室中容下的学生尽可能多,即需要搬出教室的学生数量尽可能少,请你输出搬出教室人数最少,且字典序最小的方案。

输入

输入第一行有两个整数n和m,分别表示有n个男生和n个女生,有m个朋友关系。(1<=n<=500,1<=m<=100000)接下来m行,每行有两个整数,x和y,表示第x号男生和第y号女生是朋友

男生的编号均为[1,n],女生的编号为[n+1,2n]

输出

输出第一行包含一个整数a,表示最少需要搬出教室的人数。
输出第二行有a个整数,即a个需要搬出教室的人的编号,要求人数最少,且字典序最小

意思是:一个教室内不能有亲密关系的男女,选择要移除的人满足尽可能的少、学号尽可能的小。

思路

按照题目描述可以明确:移除人数最少代表先移除不止和一个人有关系的同学。学号尽可能的小代表着优先移除男生。它的优先级是:人数>学号。

有了这个目标,再来确定算法的数据结构,我运用了以下的数据结构:

  //维护每个学生的关系映射,一对多的关系
Map<Integer, List<Integer>> relationmap = new HashMap<>(16); //某个学生的关系具体学号
List templist = relationmap.getOrDefault(boynum, new ArrayList<>()); //存放男女生有关系的个数,男生与女生各n个,第一位不放数据。
int[] relation = new int[2*n+1];

然后利用伪代码来具体描述这个过程:

获得输入的男生人数n和关系m;
初始化relation数组,map;
for( m个关系){
接收男生与女生的关系; 将两个学号作key放入Map中; 把另一个学号作value放入map的List中; 以两个学号为下标的relation数组加一;
}
while(true){
从头到尾遍历relation数组,获得最大值的下标maxRelationIndex;
当maxRelationIndex==0,意味着当前没有亲密关系,break;
根据maxRelationIndex获得map中的关系结合list; for(list){
遍历list,将对应的relation数组的下标-1;
}
删除以学号为索引在relation数组的记录;
记录被删除的学号。
}
输出记录:

代码实现

 import java.util.*;

 /**
* TODO
* @Author: HILL
* @date: 2019/8/25 9:50
*
**/
public class Main {
public static void main(String[] args) { //维护关系映射
Map<Integer, List<Integer>> relationmap = new HashMap<>(16);
//男女生人数
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt(); //存放男女生有关系的个数
int[] relation = new int[2*n+1]; for (int i=0;i<m;i++){
int boynum = sc.nextInt();
int girlnum = sc.nextInt(); //添加男生关系映射
List templist = relationmap.getOrDefault(boynum, new ArrayList<>());
templist.add(girlnum);
relationmap.put(boynum,templist);
//添加女生关系映射
templist = relationmap.getOrDefault(girlnum, new ArrayList<>());
templist.add(boynum);
relationmap.put(girlnum,templist);
//维护每个人的关系度的权值,越大代表与越多人有关系
relation[girlnum]++;
relation[boynum]++; }
List<Integer> result = new ArrayList<>();
while (true){
int maxRelationIndex = 0; //从头到尾遍历,优先移除男生
for (int i=1 ;i<relation.length;i++ ){
if (relation[i]>maxRelationIndex){
maxRelationIndex = i;
}
}
//当教室里没有亲密关系时
if (maxRelationIndex == 0){
break;
} //优先移除与最多人有关系的学生
relation[maxRelationIndex] = 0;
//查出所有与被移除学生有关系的学生
List<Integer> list = relationmap.get(maxRelationIndex);
//将它们的关系计数-1
list.forEach(i-> relation[i]--); //将移除的学生加入到结果集
result.add(maxRelationIndex);
relationmap.remove(maxRelationIndex);
}
System.out.println(result.size());
result.forEach(num->System.out.print(num+" ")); }
}

提醒

以上代码仅供交流参考,用例不一定全部通过,因为当我想出来时已经没时间了。从总体上分析,性能估计不会很高,毕竟一个算法下来会有两次循环,同时空间复杂度也比较高。但能做一步是一步嘛,后面再看看能不能换个思路。

JD面试 || 移除教室人数的更多相关文章

  1. jd面试之感

    一面问题:问题都回答的很好,顺利进入二面 1.单点登录的改造和原理 2.hashmap 3.jvm:堆.方法区.栈,本地方法栈,gc,gc的方式 4.spring的ioc.aop的实现方式cglib和 ...

  2. HDU 2242 考研路茫茫——空调教室 无向图缩环+树形DP

    考研路茫茫——空调教室 Problem Description 众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更 ...

  3. HDU 2242 考研路茫茫----空调教室

    传送门 考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  4. 考研系列 HDU2242之空调教室 tarjan

    众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更是引起人们无限YY. 一个炎热的下午,Lele照例在教室睡觉的时 ...

  5. HDU2242 考研路茫茫——空调教室 (双联通分+树形DP)

    考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. 开篇词The Start以及[Vjudge][HDU2242]空调教室

    开篇 这是我写的第一篇记录好题的博客,也是博客园上我发布的第一篇博客. 以后我的所有博客都将在洛谷和博客园上同时发布,同志们有兴趣的在哪里都可以看一看. [https://www.luogu.com. ...

  7. FZU 1894 志愿者选拔(单调队列)

    传送门 Description 世博会马上就要开幕了,福州大学组织了一次志愿者选拔活动.参加志愿者选拔的同学们排队接受面试官们的面试.参加面试的同学们按照先来先面试并且先结束的原则接受面试官们的考查. ...

  8. FZU1894 单调队列

    S - 1019 Time Limit:1500MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Sta ...

  9. FZU 1894 (双端队列)

    Problem 1894 志愿者选拔 Accept: 1166    Submit: 3683 Time Limit: 1500 mSec    Memory Limit : 32768 KB  Pr ...

随机推荐

  1. Oracle 学习笔记二

    一.oracle通用函数vnl(a,b) 用于任何类型,如果a的值不为null返回a的值否则返回b的值 条件判断oracle中可以使用 case 字段 when 条件1 then 表达式1 when ...

  2. 个人永久性免费-Excel催化剂功能第24波-批量发送邮件并指点不同附件不同变量

    批量发送邮件功能,对高级OFFICE用户来说,第1时间会想到使用WORD的邮件合并功能.但对于需要发送附件来说,邮件合并功能就无能为力,同样还有的限制是用户电脑上没有安装OUTLOOK,同样也不能发送 ...

  3. HIVE之 DDL 数据定义 & DML数据操作

    DDL数据库定义 创建数据库 1)创建一个数据库,数据库在 HDFS 上的默认存储路径是/user/hive/warehouse/*.db. hive (default)> create dat ...

  4. [leetcode] 64. Minimum Path Sum (medium)

    原题 简单动态规划 重点是:grid[i][j] += min(grid[i][j - 1], grid[i - 1][j]); class Solution { public: int minPat ...

  5. websocket的加密和解密过程

    加密: import struct msg_bytes = "the emperor has not been half-baked in the early days of the col ...

  6. C# 不同访问符的访问级别

    public----成员可以由任何代码访问. private----成员只能由类中的代码访问(如果没有使用任何关键字,就默认使用这个关键字). internal----成员只能由定义它的项目(程序集) ...

  7. MVC设计模式与Java Web经典三层架构

    MVC设计模式 MVC的概念 首先我们需要知道MVC模式并不是javaweb项目中独有的,MVC是一种软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控 ...

  8. C#编程之自动实现的属性

    在 C# 3.0 及更高版本,当属性访问器中不需要任何其他逻辑时,自动实现的属性会使属性声明更加简洁.它们还允许客户端代码创建对象.当你声明以下示例中所示的属性时,编译器将创建仅可以通过该属性的 ge ...

  9. Python 学习笔记(1)Python容器:列表、元组、字典与集合

    Python容器:列表.元组.字典与集合 列表: 1.列表 的创建 使用[ ] 或者 list()创建列表:empty_list = [ ] 或者 empty_list= list() 使用list( ...

  10. linux初学者-网络管理篇

    linux初学者-网络管理篇 linux学习中,网络管理是非常重要的一个内容,本篇将会介绍一些ip.网关.DNS配置的一些基本内容. 1.ip配置 1.1.ip查询  在linux系统中一般可以使用& ...