zoukankan      html  css  js  c++  java
  • 气球游戏-2019腾讯笔试

    气球游戏-2019腾讯笔试

    小Q在进行射击气球的游戏,如果小Q在连续T枪中打爆了所有颜色的气球,将得到一只QQ公仔作为奖励。(每种颜色的球至少被打爆一只)。

    这个游戏中有m种不同颜色的气球,编号1到m。

    小Q一共有n发子弹,然后连续开了n枪。

    小Q想知道在这n枪中,打爆所有颜色的气球最少用了连续几枪?

    输入格式

    第一行包含两个整数nm

    第二行包含n个整数,分别表示每一枪打中的气球的颜色,0表示没打中任何颜色的气球。

    输出格式

    一个整数表示小Q打爆所有颜色气球用的最少枪数。

    如果小Q无法在这n枪打爆所有颜色的气球,则输出-1

    数据范围

    1≤n≤(10^6),
    1≤m≤2000

    输入样例:

    12 5
    2 5 3 1 3 2 4 1 0 5 4 3
    

    输出样例:

    6
    

    样例解释

    有五种颜色的气球,编号15

    游客从第二枪开始直到第七枪,这连续六枪打爆了5 3 1 3 2 4这几种颜色的气球,包含了从15的所有颜色,所以最少枪数为6

    解法一:双指针算法

    贪心思想,用指针ij维护区间[i, j],移动j扩大区间使得区间内包含所有颜色气球,当满足时,移动i指针使得[i,j]区间变小依然能满足包含所以颜色的气球,此时更新一次答案(区间大小);直到遍历完整个数组。

    i,j都只增不减,因此时间复杂度为O(n);需要维护区间内每种气球的数量,以及一个HashSet 快速判断区间内气球的种类数量,或者直接使用HashMap,因此空间复杂度为O(m)

    import java.util.*;
    public class Main {
        static int search(int[] a, int n, int m) {
            int[] cnt = new int[m+1];
            Set<Integer> set = new HashSet<>();
            int res = -1;
            int i = 0, j = 0;
            while(i <= j && j < n) {
                cnt[a[j]]++;
                if(a[j] != 0) set.add(a[j]);
                if(set.size() >= m) {
                    while(i < j) {
                        if(a[i] != 0 && cnt[a[i]] == 1)
                            break;
                        cnt[a[i]]--;
                        i++;
                    }
                    if(res == -1 || j-i+1 < res) res = j-i+1;
                }
                // System.out.println(i+"---"+j);
                j++;
            }
            return res;
        }
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[] a = new int[n];
            for(int i=0;  i< n; i++)
                a[i] = sc.nextInt();
            System.out.println(search(a, n, m));
        }
    }
    

    解法二、二分查找(较为暴力)

    如果没想到第一种方法,则可以暴力做。显然,答案一定在区间[m,n]内,二分查找答案,时间复杂度为O(log(n-m))。判断k是否为答案时间复杂度为O(n),因此整个程序时间复杂度O(nlogn)。大致计算(10^6 imes log_2^{10^6}approx 10^6 imes log_2^{2^{20}}=2 imes 10^7)

    时间上依然可以接受;空间复杂度同上。

    import java.util.*;
    public class Main {
        static int search(int[] a, int l, int r){
            int m=l, n = r;
            Set<Integer> set = new HashSet<>();
            int[] cnt = new int[m+1];
            for(int i=0; i < n; i++) 
                if(a[i] != 0) 
                    set.add(a[i]);
            if(set.size() < m) return -1;
    
            while(l < r) {
                int mid = (l+r)/2;
                set.clear();
                Arrays.fill(cnt,0);
                for(int i=0; i < n; i++) {
                    if(a[i] != 0 && !set.contains(a[i])) 
                        set.add(a[i]);
                    cnt[a[i]]++;
                    if(i >= mid) {
                        cnt[a[i-mid]]--;
                        if(a[i-mid] != 0 && cnt[a[i-mid]]<= 0)
                            set.remove(a[i-mid]);
                    }
                    if(set.size() >= m) break;
                }
                if(set.size() >= m)
                    r=mid;
                else 
                    l=mid+1;
            }
            return l;
        }
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[] a = new int[n];
            for(int i=0; i < n; i++)
                a[i] = sc.nextInt();
            
            System.out.println(search(a, m, n));
        }
    }
    
  • 相关阅读:
    CSS选择器及优先级
    iframe中跨域页面访问parent的方法
    网页外链用了 target=_blank,结果悲剧了
    CarbonData:大数据融合数仓新一代引擎
    补习系列(14)-springboot redis 整合-数据读写
    python读写配置文件使用总结与避坑指南
    【云速建站】后台配置邮费
    解析:区块链的本质是伴随信息社会产生的一种新型生产关系
    用“黑科技”产放心粮,种地竟然和想象中有点不一样
    【云速建站】按照给定模板从0开始编辑网站页面
  • 原文地址:https://www.cnblogs.com/lixyuan/p/12912756.html
Copyright © 2011-2022 走看看