zoukankan      html  css  js  c++  java
  • 气球游戏腾讯面试题滑动窗口解法

    气球游戏

    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);
        }
    }
    
  • 相关阅读:
    Python全栈 MySQL 数据库 (表字段增、删、改、查、函数)
    Python全栈 MySQL 数据库 (简述 、安装、基本命令)
    Python全栈工程师(异常(高级)、运算符重载)
    Python全栈工程师(多继承、函数重写)
    【洛谷P3796】(模板)AC自动机(加强版)
    【洛谷P3808】(模板)AC自动机(简单版)
    【洛谷P3919】(模板)可持久化数组(可持久化线段树/平衡树)
    【洛谷P3834】(模板)可持久化线段树 1(主席树)
    【洛谷P3369】(模板)普通平衡树
    [USACO12FEB]牛券Cow Coupons
  • 原文地址:https://www.cnblogs.com/csh24/p/14725465.html
Copyright © 2011-2022 走看看