liuzhch1

LeetCode 76.最小覆盖字串 | 滑动窗口 | 解题思路及代码

最小覆盖字串

原题: 76. Minimum Window Substring

题目描述:
给定两个字符串,st,求s的最短子字符串,使其包含t中的所有字符(包含重复的)。

思路:
滑动窗口
先使用 Map ori 统计t中所有的字符及其个数,用另外一个 Map cnt 统计目前滑动窗口中出现的t中字符的个数。还有一个数count记录cnt中还需要的字符个数。对于每个字符来说,它在cnt中的频率可能会高于ori,如果大于ori中对应的频率,那么我们只算ori中出现的频率。

使用左右双指针,右指针从左到右扫描,如果右指针指向的字符在t中出现,那么把cnt中对应的字符频率加一。如果出现并且出现的次数小于ori(也就是应该出现的次数),那就说明这个滑动窗口中的目标字符++,我们把count减少1。

如果count=0,那就说明现在的滑动窗口包含了所有的目标字符(及重复)。现在开始把左指针向右移动。每次移动检测指向的值是否在ori中,若在,并且cnt中的值大于ori中的值,说明该字符的频率比所需的频率高,将其频率--,继续右移左指针。如果不在ori中,那就是无关字符,直接右移左指针。

直到左指针指向的值在cnt中的频率等于ori中的频率,此时我们把其cnt中的频率-1。这时的滑动窗口包含了所有字符的对应频率,并且窗口的左右都没有冗余字符。如果窗口长度小于目前所遇到的最小长度,则更新记录左右指针的位置。最后右移一次左指针,开始下一轮循环。

直到右指针的位置等于s的长度了,说明窗口滑动完了。如果有符合要求的窗口被记录下来。返回对应的子字符串,否则返回""

代码:
Java

import java.util.HashMap;
import java.util.Map;

class Solution {
    Map<Character, Integer> ori = new HashMap<Character, Integer>();
    Map<Character, Integer> cnt = new HashMap<Character, Integer>();

    public String minWindow(String s, String t) {
        int sLen = s.length(), tLen = t.length();
        int l = 0, r = -1, count = tLen;
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
        for (int i = 0; i < tLen; i++) {
            char c = t.charAt(i);
            ori.put(c, ori.getOrDefault(c, 0) + 1);
        }
        while (r < sLen) {
            r++;
            if (r < sLen && count != 0 && ori.containsKey(s.charAt(r))) {
                if (cnt.getOrDefault(s.charAt(r), 0) < ori.get(s.charAt(r))) {
                    count--;
                }
                cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
            }
            if (count == 0 && r < sLen) {
                while (true) {
                    if (cnt.getOrDefault(s.charAt(l), 0) == 0) {
                        l++;
                    } else if (cnt.get(s.charAt(l)) > ori.get(s.charAt(l))) {
                        cnt.put(s.charAt(l), cnt.get(s.charAt(l)) - 1);
                        l++;
                    } else {
                        break;
                    }
                }
                cnt.put(s.charAt(l), cnt.get(s.charAt(l)) - 1);
                count++;
                if (r - l < len) {
                    len = r - l;
                    ansL = l;
                    ansR = r+1;
                }
                l++;
            }
        }
        return ansL == -1 ? "" : s.substring(ansL, ansR);
    }
}

posted on 2022-03-27 11:46  liuzhch1  阅读(147)  评论(0编辑  收藏  举报

导航