力扣(leetcode) :76. 最小覆盖子串(滑动窗口问题)

题目:给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
在这里插入图片描述

滑动窗口特点
建立左右指针,先移动右指针,再移动左指针。

解题思路
1.建立左右指针,字符串用哈希表存储
2.先滑动右指针,直到满足sMap满足tMap,再移动左指针,使得字符串长度最小
3.当左指针右移不满足tMap时,继续移动右指针

使用的结构
哈希表,迭代器;
(当然也可以用int数组代替,利用ASCII表 )

代码如下:

import java.util.Map;
import java.util.HashMap;	//哈希表
import java.util.Scanner;
import java.util.Iterator;  //迭代器
public class Main {
	static Map<Character,Integer> ms= new HashMap<Character,Integer>();
	static Map<Character,Integer> mt= new HashMap<Character,Integer>();
	public static void main(String[] args) {
		Scanner in = new Scanner (System.in);
		
		String s=in.next();  	String t=in.next();
		//因为该字符串有重复数字  所以不能直接put() //mt.put(t.charAt(i), i);
		for(int i=0;i<t.length();i++)
			mt.put(t.charAt(i), mt.getOrDefault(t.charAt(i),0)+1);
		int l=0, r=-1, kl=0, kr=0;
					  //表示is的开头位置和结尾位置
		int len=Integer.MAX_VALUE;
		int slen=s.length();
		int tloc=0;
		while(r<slen)
		{
			r++;
			if(r<slen&&mt.containsKey(s.charAt(r))) //s(r)出现在t中
				ms.put(s.charAt(r), ms.getOrDefault(s.charAt(r),0)+1);
				//ms哈希表存入该字符
			while(check()&&l<=r)
			{
				if(r-l+1<len)
				{
					len=r-l+1; 
					kl=l; kr=l+len;
				}
				if(mt.containsKey(s.charAt(l)))  //如果左指针出现在t中
					ms.put(s.charAt(l), ms.getOrDefault(s.charAt(l),0)-1);
					//因为左指针要右移, 所以ms中要减去一个
				l++;
			}
		}
		if(len==Integer.MAX_VALUE)  //没有满足的子串
			System.out.println("");
		else
		{
			String s0=s.substring(kl, kr);
			System.out.println(s0);
		}
	}
	static boolean check()
	{   //迭代器
		Iterator it=mt.entrySet().iterator();
		while(it.hasNext()) 
		{
			Map.Entry entry =(Map.Entry)it.next();
			Character key=(Character) entry.getKey();
			Integer val = (Integer) entry.getValue();
			//如果ms中的某个字符少于mt或不存在,比对失败
			if(ms.getOrDefault(key, 0)<val)
				return false;
		}
		return true;
	}
}

难点:

  • Map.getOrDefault(Object key, V defaultValue)方法:

当Map中有这个key时,就使用原来的value; 没有就使用该默认值defaultValue
(参考:https://blog.csdn.net/weixin_43263961/article/details/86513880)

  • 迭代器(Iterator)
    Iterator it = map.entrySet().iterator();
    it.next(): 返回序列中的下一个元素(首次使用返回第一个元素)
    it.hasNext(): 判断序列中是否还有元素
    (参考:①https://www.cnblogs.com/zzzzw/p/4945915.html
    ②https://www.cnblogs.com/lxqiaoyixuan/p/7156944.html)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值