zoukankan      html  css  js  c++  java
  • [牛客题霸-高频算法面试题]那些插队的人

    题目描述

    你有一个长度为 n 的队伍,从左到右依次为 1~n,有 m 次插队行为,用数组 cutIn 进行表示,cutIn 的元素依次代表想要插队的人的编号,每次插队,这个人都会直接移动到队伍的最前方。你需要返回一个整数,代表这 m 次插队行为之后,有多少个人已经不在原来队伍的位置了。

    示例1

    输入:3,[3, 2, 3]

    输出:2

    说明:

    初始队伍为 [1, 2, 3]

    3 开始插队 [3, 1, 2]

    2 开始插队 [2, 3, 1]

    3 开始插队 [3, 2, 1]

    所以2还在原来的尾置,3和1两个人已经不在原来的位置了。

     

    思路

    先来看一个例子15 [10, 4, 6, 5, 9, 7, 3, 3, 9, 10],我们来模拟一下插队过程。

    第一次:10

    第二次:4 10

    第三次:6 4 10

    第四次:5 6 4 10

    第五次:9 5 6 4 10

    第六次:7 9 5 6 4 10

    第七次:3 7 9 5 6 4 10

    第八次:3 7 9 5 6 4 10

    第九次:9 3 7 5 6 4 10

    第十次:10 9 3 7 5 6 4

    最终位置:10 9 3 7 5 6 4 1 2 8 11 12 13 14 15

    可以发现,队伍最终的排列是由最后一次插队决定的,然后没插队的人全部依次排在插队的人的后面。因此从后往前遍历cutIn数组,遇到重复的跳过。

    判断是否还在原位置时,将队伍分为两部分计算:插队的人和没插队的人。对于插队的人,直接判断位置和序号是否匹配;设插队的人中最大序号为max,对于没插队的人,序号>max的一定还在原来队伍中的位置,<max的一定不在原来位置(结合生活实际,很好理解:我们在排队的时候,不太关心排在自己前面的人的位置变动,因为这不会影响到我们自己的等待时间,但是一旦排在自己后面的人插到自己前面,我们就会很不爽,因为这会造成自己的等待时间边长)

    题目让求有多少个人已经不在原来队伍的位置,我们可以逆向思维计算有多少人还在原来的位置,然后减去这个值就能得到位置改变的总人数。

    下图展示了例子中队伍的判断情况:

    tips:

    Set、HashMap等数据结构都可以处理重复值。HashMap的key值是编号这个没问题,对于value类型的选择,我直接用true/false来记录是否访问过;也可以使用Integer来记录编号为key的人在队伍中的最终位置。其实仔细观察会发现我们全程并不关心value值是多少(我们是通过map.containsKey()来判断是否重复的),也就是说HashMap完全可以退化成Set,不过实际提交代码时发现使用HashMap的程序运行时间更短,所以下面的代码还是用HashMap了。

    JAVA代码

    public class Solution {
        /**
         * 计算有多少个人最终不在自己原来的位置上
         * @param n int整型 队伍总长
         * @param cutIn int整型一维数组 依次会插队到最前方的人的编号
         * @return int整型
         */
        public int countDislocation (int n, int[] cutIn) {
            if(cutIn.length == 0) return 0;
            HashMap<Integer, Boolean> visited = new HashMap<>();
            int max = 0, same = 0, number = 1;
            for(int i = cutIn.length - 1; i >= 0; i--) {
                if(!visited.containsKey(cutIn[i])) {
                    visited.put(cutIn[i], true);
                    if(cutIn[i] == number++) same++;
                    max = Math.max(max, cutIn[i]);
                }
            }
            return max - same;
        }
    }
  • 相关阅读:
    Stack frame
    How a stack frame works 栈帧的要素与构建步骤
    Symbol Table
    函数调用栈实例研究
    崩溃日志的实例
    符号表的作用和地位
    A C compiler that parses this code will contain at least the following symbol table entries
    前复权是从今天的价格倒推 后复权是从上市价格前推 不复权就是原始K线。
    Thinkphp5+PHPExcel实现批量上传表格数据功能
    PHP 开发API接口签名验证
  • 原文地址:https://www.cnblogs.com/barryyeee/p/12839608.html
Copyright © 2011-2022 走看看