zoukankan      html  css  js  c++  java
  • JD面试 || 移除教室人数

    在昨天参加了东哥的笔试,选择题做的还算可以,但是还有道编程题和关于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个需要搬出教室的人的编号,要求人数最少,且字典序最小

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

    思路

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

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

    1  //维护每个学生的关系映射,一对多的关系
    2   Map<Integer, List<Integer>> relationmap = new HashMap<>(16);
    3 
    4  //某个学生的关系具体学号
    5  List templist = relationmap.getOrDefault(boynum, new ArrayList<>());
    6 
    7  //存放男女生有关系的个数,男生与女生各n个,第一位不放数据。
    8  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数组的记录;
        记录被删除的学号。
    }
    输出记录:

    代码实现

     1 import java.util.*;
     2 
     3 /**
     4  * TODO
     5  * @Author: HILL
     6  * @date: 2019/8/25 9:50
     7  *
     8 **/
     9 public class Main {
    10     public static void main(String[] args) {
    11 
    12         //维护关系映射
    13         Map<Integer, List<Integer>> relationmap = new HashMap<>(16);
    14         //男女生人数
    15         Scanner sc = new Scanner(System.in);
    16         int n = sc.nextInt();
    17         int m = sc.nextInt();
    18 
    19         //存放男女生有关系的个数
    20         int[] relation = new int[2*n+1];
    21 
    22 
    23         for (int i=0;i<m;i++){
    24             int boynum = sc.nextInt();
    25             int girlnum = sc.nextInt();
    26 
    27             //添加男生关系映射
    28             List templist = relationmap.getOrDefault(boynum, new ArrayList<>());
    29             templist.add(girlnum);
    30             relationmap.put(boynum,templist);
    31             //添加女生关系映射
    32             templist = relationmap.getOrDefault(girlnum, new ArrayList<>());
    33             templist.add(boynum);
    34             relationmap.put(girlnum,templist);
    35             //维护每个人的关系度的权值,越大代表与越多人有关系
    36             relation[girlnum]++;
    37             relation[boynum]++;
    38 
    39 
    40         }
    41         List<Integer> result = new ArrayList<>();
    42         while (true){
    43             int maxRelationIndex = 0;
    44 
    45             //从头到尾遍历,优先移除男生
    46             for (int i=1 ;i<relation.length;i++ ){
    47                 if (relation[i]>maxRelationIndex){
    48                     maxRelationIndex = i;
    49                 }
    50             }
    51             //当教室里没有亲密关系时
    52             if (maxRelationIndex == 0){
    53                 break;
    54             }
    55 
    56             //优先移除与最多人有关系的学生
    57             relation[maxRelationIndex] = 0;
    58             //查出所有与被移除学生有关系的学生
    59             List<Integer> list = relationmap.get(maxRelationIndex);
    60             //将它们的关系计数-1
    61             list.forEach(i-> relation[i]--);
    62 
    63             //将移除的学生加入到结果集
    64             result.add(maxRelationIndex);
    65             relationmap.remove(maxRelationIndex);
    66         }
    67         System.out.println(result.size());
    68         result.forEach(num->System.out.print(num+" "));
    69 
    70     }
    71 }

    提醒

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

  • 相关阅读:
    在上传图片前,提供预览功能(Javascript)
    C#和Visual Basic渐行渐远
    Silverlight入门介绍和应用实践
    一道面试试题:试介绍ASP.NET页面之间数据传递的几种方法
    建立基于AJAX样式的文件上传
    CSS 命名规范
    Microsoft出招,Adobe接招,我们只好择优使用
    最近要使用User Interface Process Application Block for .NET(微软net开发架构)
    利用office web component打造精品图表(一)
    滚动条SCROLLBAR
  • 原文地址:https://www.cnblogs.com/hill1126/p/11408468.html
Copyright © 2011-2022 走看看