2019腾讯暑假实习笔试编程题(第四题)

昨晚做的笔试题,第一次参加线上笔试,最后半个小时走神走的厉害,有种干坐着等待着死亡降临的感觉……这道题没做出来,很可惜。 重新理清了思路,写出来了,题目如下 file 

一开始我想到了leetcode里面的最小子串,奈何太菜几个关键点忘了。leetcode原址

思路说难也不难,说容易也不容易。首先有几个关键点

  • 何时更新最短子串长度?
  • 如何判定已包含所有数字?
  • 什么时候滑动窗口?

接着我先说明下几个参数

  • 开枪的总次数 total
  • 气球颜色数量 target
  • 滑动窗口的左右指针 left right
  • 最短子串长度 min

何时更新最短子串长度?

  • 最短子串长度初始值为开枪的总次数 total,如果没有比total小的,说明不满足要求,得不到QQ公仔。
  • 当子串第一次包含所有的数字时,更新最短子串长度min。

那么第二个问题来了,如何判定已包含所有数字?

  • 需要一个hashMap来统计每个颜色的数量,这题每种颜色只需要打一枪,但是可以延伸不同颜色不同数量的题目。
  • 打掉了一个颜色的气球,就相应的在hashMap中KEY值对应value减一
  • 同时还需要一个count来统计剩余颜色数量
  • 如果打掉的颜色气球已经打满足要求,不需要再打了,此时的count就不减。因为count只记录剩下需要打的颜色

什么时候滑动窗口? 既然要算最短长度,那么肯定要遍历数组的所有情况。那什么时候开始滑呢? 如果我第一次滑动之前right指针往右移,第一次满足了我已经打满了所有颜色的气球的情况 即剩余颜色数量count=0时,这时候我们需要判断现在是不是最短的子串长度,那么left往左移,开始滑动窗口

代码如下:

import java.util.HashMap;
import java.util.Scanner;

public class Solution {
	public static void main(String[] args) {
		HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
		Scanner scanner = new Scanner(System.in);
		int total = scanner.nextInt();
		int target = scanner.nextInt();
		int[] qiang = new int[total];
		for(int i =0;i<total;i++) {
			qiang[i]=scanner.nextInt();			
		}
		for(int j=0;j<target;j++) {
			map.put(j+1, 1);
		}
		
		int left=0;
		int count=target;
		int result=0;
		int min = total;
		for(int right=0;right<total;right++) {
				if(map.containsKey(qiang[right])) {
					map.put(qiang[right], map.get(qiang[right])-1);
					if(map.get(qiang[right])>=0) {
						count--;
					}
				}
				
				while(count==0) {
					if(right-left<min) {
						min= right-left;						
					}
					if(map.containsKey(qiang[left])) {
						map.put(qiang[left], map.get(qiang[left])+1);
						if(map.get(qiang[left])>0) count ++;
					}
					left++;
				}						
		}		
		System.out.println(min==total?-1:min+1);
	}
}

如果有更好的意见和建议或者疑惑,都可以在下面留言

多谢浏览

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值