⭐LeetCode 76. Minimum Window Substring

题目描述

在这里插入图片描述

知识点

滑动窗口

结果

在这里插入图片描述

实现

码前思考

  1. 这道题目是我学习“滑动窗口”的例题,所以我没有对这道题目进行过独立的思考,是按照别人的思路写的;

代码实现

//滑动窗口问题
//使用双指针进行解题

class Solution {
public:
    string minWindow(string s, string t) {
        //定义双指针,初始化都为最左边
        int left = 0;
        int right = 0;
        
        //定义最小的长度,初始化为无限大
        int len = INT_MAX;
        //存储最小窗口开始的地方,这样start~start+len就是窗口的字符串了
        int start = 0;

        //两个hash,用于存储匹配需求和匹配实际
        unordered_map<char,int> needs;
        unordered_map<char,int> window;

        //初始化needs
        for(int i=0;i<t.size();i++){
            needs[t[i]]++;
        }

        //表示匹配情况,初始为都没有匹配
        int match = 0;

        while(right < s.size()){    //只要还在范围之内
            
            //如果当前字符是needs集合里面的字符
            if(needs.count(s[right])){
                window[s[right]]++;
                //如果满足了匹配条件
                if(window[s[right]] == needs[s[right]]){
                    match++;
                }
            }

            //如果match达到了相应的数量
            while(match == needs.size()){
                //那么接下来就是记录长度并且滑动我们的left指针
                if(right - left + 1 < len ){    //如果长度小于当前最短长度,那么要进行更新
                    len = right - left + 1;
                    start = left;
                }
                //开始进行右移,如果这个字符是needs里面需要的话
                if(needs.count(s[left])){
                    window[s[left]]--;
                    if(window[s[left]] < needs[s[left]]){
                        match--;
                    }
                }
                left++;
            }
            right++;
        }

        string res = ((len == INT_MAX) ? "":s.substr(start,len));

        return res;
    }
};

上面代码写错了!!!!!!!!!!!!!!!!!错在下面:

if(needs.count(s[left])){
    window[s[left]]--;
    if(window[s[left]] < needs[s[left]]){
        match--;
    }
}

代码实现

//滑动窗口问题
//使用双指针进行解题

class Solution {
public:
    string minWindow(string s, string t) {
        //定义双指针,初始化都为最左边
        int left = 0;
        int right = 0;
        
        //定义最小的长度,初始化为无限大
        int len = INT_MAX;
        //存储最小窗口开始的地方,这样start~start+len就是窗口的字符串了
        int start = 0;

        //两个hash,用于存储匹配需求和匹配实际
        unordered_map<char,int> needs;
        unordered_map<char,int> window;

        //初始化needs
        for(int i=0;i<t.size();i++){
            needs[t[i]]++;
        }

        //表示匹配情况,初始为都没有匹配
        int match = 0;

        while(right < s.size()){    //只要还在范围之内
            
            //如果当前字符是needs集合里面的字符
            if(needs.count(s[right])){
                window[s[right]]++;
                //如果满足了匹配条件
                if(window[s[right]] == needs[s[right]]){
                    match++;
                }
            }

            //如果match达到了相应的数量
            while(match == needs.size()){
                //那么接下来就是记录长度并且滑动我们的left指针
                if(right - left + 1 < len ){    //如果长度小于当前最短长度,那么要进行更新
                    len = right - left + 1;
                    start = left;
                }
                //开始进行右移,如果这个字符是needs里面需要的话
                if(needs.count(s[left])){
                    if(window[s[left]] == needs[s[left]]){
                        match--;
                    }
                    window[s[left]]--;
                }
                left++;
            }
            right++;
        }

        string res = ((len == INT_MAX) ? "":s.substr(start,len));

        return res;
    }
};

码后反思

  1. 在这道题目里面,滑动窗口[left,right]表示的是以s[left]为首的字符串,能够满足匹配字符串t中的所有字符的最短字符串是[left,right]。这个定义读起来很抽象,但是如果结合滑动窗口的过程理解就不难了;
  2. 使用滑动窗口,我们始终要明确下面三个方面的知识:
    • right右移是寻找可行解的过程;
    • left右移是寻找最优解的过程;
    • 理解滑动窗口[left,right]表达的含义是什么?
发布了173 篇原创文章 · 获赞 3 · 访问量 5215

猜你喜欢

转载自blog.csdn.net/yc_cy1999/article/details/105682740