氣球遊戲騰訊面試題滑動視窗解法

?沙漠駱駝發表於2021-05-02

氣球遊戲

1 背景

面試騰訊,面試官感覺很忙,一邊工作一邊面試,一上來自我介紹都省了,直接就是這道題,讓半小時寫出來,面試的時候思路理出來了,但是平時滑動視窗寫的少,自然是沒寫出來了,假期特地惡補了滑動視窗。發現網上還很少這道題的解法,於是簡單整理了一下。題目雖然叫氣球遊戲,但是本質其實還是“最小覆蓋字串”。

2 題目描述

小Q在進行射擊氣球的遊戲,如果小Q在連續T槍中打爆了所有顏色的氣球,將得到一隻QQ公仔作為獎勵。(每種顏色的氣球至少被打爆一隻)。
這個遊戲中有m種不同顏色的氣球,編號1到m。小Q一共有n發子彈,然後連續開了n槍。小Q想知道在這n槍中,打爆所有顏色的氣球最少用了連續幾槍?

  • 輸入描述:

第一行兩個空格間隔的整數數n,m。n<=1000000 m<=2000

第二行一共n個空格間隔的整數,分別表示每一槍打中的氣球的顏色,0表示沒打中任何顏色的氣球。

  • 輸出描述:

一個整數表示小Q打爆所有顏色氣球用的最少槍數。如果小Q無法在這n槍打爆所有顏色的氣球,則輸出-1

  • 示例1

輸入:
12 5
2 5 3 1 3 2 4 1 0 5 4 3
輸出:
6

  • 示例2

輸入:
12 5
2 5 3 1 3 2 4 1 5 0 4 3
輸出: 5

3 題解

  • 思路:
    滑動視窗演算法。先向右不斷擴大視窗,滿足條件是,再從左邊縮小視窗找到最優解。

  • 實現:

/**
 * @author csh
 * @date 2021/5/1
 */
public class BalloonGame {
    private Integer balloonGame(int n, int m, int[] balloon) {
        // 定義視窗和need
        HashMap<Integer, Integer> need = new HashMap<>();
        HashMap<Integer, Integer> window = new HashMap<>();
        // m種顏色的氣球
        for (int i = 1; i <= m; i++)
            need.put(i, 1);
        // 控制視窗用的指標
        int left = 0, right = 0;
        // window中滿need條件的個數
        int valid = 0;
        int res = Integer.MAX_VALUE;
        while (right < n) {
            // 向右擴大視窗
            int num = balloon[right];
            right++;
            if (need.containsKey(num)) {
                window.put(num, window.getOrDefault(num, 0) + 1);
                if (window.get(num).equals(need.get(num))) valid++;
            }

            while (valid == m) {
                // 記錄最小視窗
                res = Math.min(res, right - left);
                // 縮小視窗
                int num2 = balloon[left];
                left++;
                if (need.containsKey(num2)) {
                    if (window.get(num2).equals(need.get(num2))) valid--;
                    window.put(num2, window.getOrDefault(num2, 0) - 1);
                }
            }
        }
        return res == Integer.MAX_VALUE ? -1 : res;
    }

    public static void main(String[] args) {
        int[] balloon = new int[]{2, 5, 3, 1, 3, 2, 4, 1, 0, 5, 4, 3}; // 答案:6
        int[] balloon2 = new int[]{2, 5, 3, 1, 3, 2, 4, 1, 5, 0, 4, 3}; // 答案:5
        BalloonGame main = new BalloonGame();
        Integer res = main.balloonGame(12, 5, balloon2);
        System.out.print("最少需要:" + res);
    }
}

相關文章