携程笔试(惨败经历)第一题 leetcode 253

刚开始生怕题做不完,选择题听说去年是15分钟20题,一顿乱选。

第一道选择题 树的前序遍历35421,中序遍历25431,

后序遍历应该是....? 这道题是不是有点问题,没敢仔细看就选了....

编程题更是血炸.....一道都不会。果然刷题不够多,只看看剑指offer果然不管用啊....第一次笔试就这么拉了。

明天还有美团的笔试,后天的汇报ppt还没做呢,5555555555555555。

但还是先总结一下吧,编程题第一道。

1.客服人数

输入一个n表示要输入的通话记录个数,接下来输入n行,每行为逗号相隔的两个整数,
两个数字分别代表呼入时间和挂断时间的时间戳。
举例:10,30,表示[10,30),代表第10秒呼入,第30秒已经挂断,
即第30秒可以接入新的来电; 每一行都是一条通话记录,通话记录已经按呼入时间由小到大排序
输出一个整数;代表最少需要多少客服,可以满足所有旅客来电不用等待。

测试样例:

6
0,30
0,50
10,20
15,30
20,50
20,65

样例输出:

5

之前没有做过类似的题,完全没有思路,瞎写了点代码,瞎猫撞上死耗子过了50%。

结束后在牛客看到大佬发答案,才知道leetcode 253跟本题高度重合....

这里贴出来找到的一个博主Java实现的代码

https://blog.csdn.net/qq_41645636/article/details/99475054?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

始终还是缺少点解释,脑子不灵光的我还是没理解啊,带着思考继续找题解,下面这个博客讲的不错

https://www.cnblogs.com/aaronliu1991/p/11774859.html

恍然大悟,其实本质上是个很简单的问题。

不管是会议室开会也好,还是客服接电话也好,对于给定的多个时间段序列,需要找到最少的数量会议室或是客服,使得过程不会堵塞,抽象成数学问题本质上是同一个东西。

就按客服接电话这个问题来讲,在某个时间段客服接电话了,什么情况下会需要多增加一个客服,防止用户等待呢?答案是下一个时段端与当前客服时间段重合则需要增加一个客服。比如[5,10]一个客服,那么下一段如果是[9,12]必定需要增加一个客服,如果是[11,12]就不需要增加新的客服。

因为只需要知道最少需要多少客服,因此可以单独对每个时间段的开始时间和结束时间进行排序。

比如输入[1,5],[4,7],[9,10],[2,3],单独对开始时间和结束时间排序,得到如下

startArray=[1,2,4,9]   endArray=[3,5,7,10],定义客服数量cnt=0.

然后从最小的开始时间找,如果startArray[startIndex]大于当前的结束时间endArray[endIndex],说明当前不存在重合时间段,那么客服数量不需要增加;如果小于endArray[endIndex],那么说明存在重合时间段,需要增加一个客服。

(最开始startIndex=0,stopIndex=0)当然对于合法输入,排序后的第一个开始时间肯定小于第一个结束时间,因此stopIndex++,cnt++.

根据上面的输入序列推一下:

1.startIndex=0,endIndex=0,cnt=0,此时1<3,==>startIndex++;cnt++

2.startIndex=1,endIndex=0,cnt=1,此时2<3,==>startIndex++;cnt++

3.startIndex=2,endIndex=0,cnt=2,此时4>3,==>endIndex++;

4.startIndex=2,endIndex=1,cnt=2,此时4<5,==>startIndex++;cnt++

5.startIndex=3,endIndex=1,cnt=3,此时9>5,==>endIndex++;

6.startIndex=3,endIndex=2,cnt=3,此时9>7,==>endIndex++;

7.startIndex=3,endIndex=3,cnt=3,此时9<10,==>startIndex++;cnt++

退出循环 最后cnt=3。

以上就是题解思路,关键代码其实很少,但是好像确实有点绕,但是想明白了其实很简单....本人就被绕了一个晚上.....

下面贴出Java程序代码实现(主函数是用来控制台输入的,看关键算法代码即可)

  public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);
        int count =Integer.parseInt(sc.nextLine().trim());

        int[][] rows =new int[count][2];
        for(int i=0;i<count;i++){
            String row =sc.nextLine();
            String[] split = row.split(",");
            rows[i][0]=Integer.parseInt(split[0]);
            rows[i][1]=Integer.parseInt(split[1]);
        }

        int res=0;
        res = calcMinStaff(rows);
        System.out.println(String.valueOf(res));

    }
    static int calcMinStaff(int[][] rows) {
        //每一行保存一个时间段,现需要对所有的时间端做一个分割
        //所有的开始时间放一起,所有的结束时间放一起
        //然后sort
        int[] startArray = new int[rows.length];
        int[] endArray =new int[rows.length];
        for(int i=0;i<rows.length;i++){
            startArray[i]=rows[i][0];
            endArray[i]=rows[i][1];
        }
        Arrays.sort(startArray);
        Arrays.sort(endArray);
        int cnt =0; //客服数量
        int eIndex=0;
        //算法关键
        for(int sIndex=0;sIndex<startArray.length;sIndex++){
            if(startArray[sIndex]<endArray[eIndex]){
                cnt++;//需要增加客服
            }
            else {
                eIndex++;//切换到下一个结束时间
            }
        }
        return cnt;
    }

牛客网的大佬用的貌似是贪心算法求解,看起来好像更能理解一点,地址如下:

https://www.nowcoder.com/discuss/398154?type=all&order=time&pos=&page=1

上面的代码时间复杂度为O(n2),另外还有一种堆排序的方法,将时间复杂度降到O(nlogn)

另外一个类似问题的介绍

https://www.jianshu.com/p/3948fda91d3d

2.海豚数量

明天做完美团笔试再更吧,又要求虐啦/(ㄒoㄒ)/~~

发布了24 篇原创文章 · 获赞 3 · 访问量 1301

猜你喜欢

转载自blog.csdn.net/qinian_ztc/article/details/105257168