题解 | #最小覆盖子串#

最小覆盖子串

https://www.nowcoder.com/practice/c466d480d20c4c7c9d322d12ca7955ac

由于需要时间复杂度O(n),所以遍历所有字符串肯定是不行的。所以考虑使用滑动窗口。

具体做法:从0位置开始,右索引每次移动一个步长,当匹配到目标字符之一时,在hashmap中的计数相应加1,并且如果左侧索引处字符计数已经超出要求时或者是非目标字符时,左侧索引可以向右循环移动。这样从左移动到右边就可以找到最小覆盖子串。

代码如下:


class Solution {
  public:
    string minWindow(string S, string T) {
        // 初始化hashmap
        unordered_map<char, int> hs, ht;
        for (auto t : T) {
            hs[t] = 0;
            ht[t]++;
        }
        int cnt = 0; // 满足条件的char的个数
        // 右索引不断向右,左索引
        int left_min = 0, right_min = -1;
        int left = 0, right = 0; //记录匹配串
        for (int i = 0, j = 0; i < S.length(); i++) {
            char cr = S[i];
            if (ht.count(cr) == 1) { // 右字符是目标字符之一
                hs[cr]++;
                if(hs[cr] == ht[cr])cnt++; // 一个目标字符满足了要求
                right = i;

                char cl = S[j];
                while (ht.count(cl) == 0 || hs[cl] > ht[cl]) { // 左侧索引处是非目标字符 或者 是目标字符,并且计数超出目标
                    if (ht.count(cl) == 1) hs[cl]--;
                    j++;
                    cl = S[j];
                }
                left = j;

                if (cnt == ht.size()) { // 找到了一个覆盖子串
                    if (right_min == -1 || right - left < right_min - left_min) { // 第一次找到 或者 新的更短
                        left_min = left;
                        right_min = right;
                    }
                }
            }
        }
        return S.substr(left_min, right_min - left_min + 1);
    }
};
全部评论

相关推荐

hso_:哈哈哈哈哈哈我没offer一样在同一道题开喷了
投递深圳同为数码等公司10个岗位
点赞 评论 收藏
分享
一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务