498 字
2 分钟
76. 最小覆盖子串

76. 最小覆盖子串#

题目:https://leetcode.cn/problems/minimum-window-substring/

思路:#

原始想法:确定一个滑动窗口,滑动窗口需要满足:子字符串中的字符数量大于等于 t 中的字符数量。如果当前滑动窗口不满足条件,那么右窗口右移,直到满足条件。当满足条件后,左窗口右移,直到丢掉一个子字符串的元素,使得滑动窗口条件不满足,这时候再判断滑动窗口是否满足条件,如果不满足,那么右窗口右移,直到结束。

伪代码:

  • left = 0,right = 0
  • while right < n:
    • check
    • if true
      • ans = min(ans, (j - i + 1))
      • left 一直右移到下一个子串元素
    • if false
      • right < n && right 一直右移到下一个子串元素

代码#

自己写的代码(cpp):

class Solution {
    public:
        string minWindow(string s, string t) {
            int sn = s.size(), tn = 0;
    
            int q[100] = {0};
            for (auto item : t) {
                if (q[item - 'A'] == 0) {
                    tn++;
                }
                q[item - 'A']++;
            }
    
            int start = 0, res = INT_MAX;
    
            int count = 0;
            int arr[100] = {0};
    
            int left = 0, right = -1;
            // left 找到第一个符合条件的元素
            while (left < sn && q[s[left] - 'A'] == 0) {
                left++;
            }
            if (left == sn) {
                return ""; // 如果没有符合条件的子串,返回空字符串
            }
    
            while (right < sn) {
                // check 检查是否满足滑动窗口的条件
                if (count >= tn) {
                    // 记录答案
                    if (right - left + 1 <= res) {
                        start = left;
                        res = right - left + 1;
                    }
                    // left 移向下一个子串元素
                    if (arr[s[left] - 'A'] == q[s[left] - 'A']) {
                        count--;
                    }
                    arr[s[left] - 'A']--;
                    do {
                        left++;
                    } while (left < sn && q[s[left] - 'A'] == 0);
                } else {
                    // right 移向下一个子串元素
                    do {
                        right++;
                    } while (right < sn && q[s[right] - 'A'] == 0);
                    if (right < sn) {
                        if (arr[s[right] - 'A'] == q[s[right] - 'A'] - 1) {
                            count++;
                        }
                        arr[s[right] - 'A']++;
                    }
                }
            }
    
            if (res == INT_MAX) {
                return ""; // 如果没有符合条件的子串,返回空字符串
            } else {
                return s.substr(start, res); // 返回符合条件的子串
            }
        }
    };
76. 最小覆盖子串
https://blog.hzau.top/posts/algorithm/76-minimum-window-substring/
作者
Dawn Journey
发布于
2025-04-23
许可协议
CC BY-NC-SA 4.0