LeetCode 76 最小覆盖子串

  • 链接 : 最小覆盖子串
  • 题意:给定一个字符串s以及t,判断 s 里包含 t 所有字母的最小子串。
  • 思路:双指针的应用——滑动窗口
    (官方题解)举个例子,S = “ABAACBAB”,T = “ABC”
    首先两个指针 left = right = 0
    在这里插入图片描述
    然后right 逐渐增加,直到窗口包含t 所有字母
    在这里插入图片描述
    这时,维护最小的窗口,所以逐渐 缩减窗口,left ++ 。如果窗口减小后,不满足条件,则right++。
    left++后,窗口依然满足条件
    此时不满足条件,right++
    在这里插入图片描述
    这就是最小的window
  • 代码:
    注释我写的很详细
class Solution {
    
    
public:
    string minWindow(string s, string t) {
    
    
    	//need是 t包含的字母, window是滑动窗口
        unordered_map<char,int> need, window;
        for(char c : t) need[c] ++;
        //left,right是窗口
        //valid 是判断满足条件与否,window内每有一个t内的字母,valid++
        int left = 0, right = 0, valid = 0;
        int start = 0, len = INT_MAX;
        while(right < s.size()){
    
    
        	//每次窗口滑动
            char tmp = s[right];
            right ++;
            //t中所有tmp,window内都有,则valid++
            if(need.count(tmp)){
    
    
                window[tmp] ++;
                if(window[tmp] == need[tmp]){
    
    
                    valid ++;
                }
            }
            //窗口内包含t内所有字母
            while(valid == need.size()){
    
    
            	//每次更新最小窗口。start和len是确定最后子串的。
            	//left和right最后不一定是最小窗口
                if(right - left < len){
    
    
                    start = left;
                    len = right - left;
                }
                //满足条件后窗口缩减
                char d = s[left];
                left ++;
                //缩减后丢失的字母在t中出现,且丢失后不满足条件。
                if(need.count(d)){
    
    
                    if(window[d] == need[d]){
    
    
                        valid --;
                    }
                    window[d] --;
                }                
            }
        }
        return len == INT_MAX ? "" : s.substr(start,len);
    }
};
  • 遇到的问题:
    1、今天另外一道题所学到的知识:
    vector< int > a(n) 。 用此种方法构造vector的长度,这样可以直接 cin>>a[i]

    2、文件流输入输出
    #define _DEBUG
    #ifdef _DEBUG
    freopen(“in.txt”,“r”,stdin);
    freopen(“out.txt”,“w”,stdout);
    #endif

    此结构是 #ifdef 标识符 ***** #endif
    如果define了标识符,那么里面的部分就会编译运行,否则不会。
    如上, #define _DEBUG,则freopen两行可以编译运行。提交的时候只需要注释掉宏定义的此句即可。

    3、INT_MAX 是头文件 limit.h 里的宏定义
    因为用INF的时候,以前都是用 0x7fffffff,就是int的最大值,除了符号位是0,其他都是1。
    INT_MAX等于此值,可以直接使用。

    4、unordered_map
    是无序的一个键值对集合。
    map有个特性,即插入后自动按照 key的值进行排序,所以是有序的。性能上应该不如 unordered_map
    声明: unordered_map<char, int> mp;
    主要方法基本和map一致。

猜你喜欢

转载自blog.csdn.net/qq_39763472/article/details/105801252
今日推荐