[牛客題霸-高頻算法面試題]那些插隊的人

題目描述

你有一個長度爲 n 的隊伍,從左到右依次爲 1~n,有 m 次插隊行爲,用數組 cutIn 進行表示,cutIn 的元素依次表明想要插隊的人的編號,每次插隊,這我的都會直接移動到隊伍的最前方。你須要返回一個整數,表明這 m 次插隊行爲以後,有多少我的已經不在原來隊伍的位置了。數組

示例1

輸入:3,[3, 2, 3]數據結構

輸出:2spa

說明:code

初始隊伍爲 [1, 2, 3]blog

3 開始插隊 [3, 1, 2]ip

2 開始插隊 [2, 3, 1]it

3 開始插隊 [3, 2, 1]io

因此2還在原來的尾置,3和1兩我的已經不在原來的位置了。class

 

思路

先來看一個例子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;
    }
}
相關文章
相關標籤/搜索