2025年- H96-Lc204--76.最小覆盖子串(子串、滑动窗口)--Java版

发布于:2025-08-19 ⋅ 阅读:(17) ⋅ 点赞:(0)

1.题目描述

在这里插入图片描述

2.思路

滑动窗口,用两个哈希表来记录当前t中字符的数量和滑动窗口的数量。
窗口滑动的同时要记录有效字符的数量。
ht:字符串t的哈希表。
hs:字符串s的哈希表。
cnt:代表窗口滑动时的有效字符的数量。
所以,
(1)i指针在第1个元素
ht:{A:1,B:1,C:1}
hs中设置两个指针,i和j,同时指向第一个元素。每次循环进行3个操作,把当前字符加入到窗口中,如果加到hs中的字符没有超过ht中字符的数量说明是有效字符,所以cnt+1。因为在窗口加入了新的字符,所以窗口左侧中会存在冗余字符所以要删,所以要右移窗口的左边界。如果cnt的数值等于ht的长度,说明已经窗口已经覆盖t的所有字符串.
hs{A:1}
cnt=1
(2)i指针在第3个元素
ht:{A:1,B:1,C:1}
hs{A:1,B:1}
cnt=2
(3)i指针在第3个元素
ht:{A:1,B:1,C:1}
hs{A:2,B:1}
cnt=2
当前hs窗口字符A超过了ht所需要的A的元素的个数,所以j向后移动。同时hs窗口A中的数量-1.
时间复杂度是O(n)
在这里插入图片描述
在这里插入图片描述

3.代码实现

class Solution {
    public String minWindow(String s, String t) {
        HashMap<Character,Integer> ht=new HashMap<>();
        HashMap<Character,Integer> hs=new HashMap<>();
        for(int i=0;i<t.length();i++)
        {
            //把t字符和字符的个数,放入到ht的哈希表中
            //记得字符串取字符用 字符串.charAt();  在哈希表中根据字母找它的值用 字符串.getOrDefault(字符,0)
            //ht.put(t.charAt(i),ht.getOrDefault(t.charAt(i),0)+1);

            char c=t.charAt(i);
            ht.put(c,ht.getOrDefault(c,0)+1);
            
        }

        //定义最小覆盖子串
        String ans="";
        //统计有效字符
        int cnt=0;
       
       //遍历hs哈希表
       for(int i=0,j=0;i<s.length();i++)
       {
        char c=s.charAt(i);
        hs.put(c,hs.getOrDefault(c,0)+1);
        //如果hs滑动窗口的当前字符的个数小于等于ht哈希表的该字符的个数,说明滑动窗口还没完全覆盖t字符串的字符,所以有效字符继续++
        if(hs.get(c)<=ht.getOrDefault(c,0))
        {
            cnt++;
        }
        //如果滑动窗口hs中某个字符的个数大于ht中该字符的个数,移动j指针,缩小窗口,删除冗余字符
        while(j<=i&&hs.getOrDefault(s.charAt(j),0)>ht.getOrDefault(s.charAt(j),0))
        {
            hs.put(s.charAt(j),hs.get(s.charAt(j))-1);
            j++;
        }
        //判断是否找到覆盖子串
        if(cnt==t.length())
        {
            if(ans.isEmpty()||ans.length()>i-j+1)
            {
                ans=s.substring(j,i+1);
               // 更新答案为 s[j..i](注意 substring 的右端是开区间,所以用 i+1)。
            }
        }
       }
       return ans;
           
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到