zoukankan      html  css  js  c++  java
  • 【算法】【字符串】Leetcode滑动窗口相关题目

    滑动窗口

    维护一个窗口,不断滑动;

    for(int l = 0, r = 0; r < s.size();)
    {
          //增大窗口
          win.add(s[r]);
          r++;
    
          //窗口右移
          while(满足某个条件)
          {
                win.remove(s[l]);
                l++;
                //更新某个值
          }
    }
    

    模板

    void slidingWin(string str, string t)
    {
    	unordered_map<int, int> hashmap, win;
    	
    	for(char c : t) hashmap[c]++;
    	
    	int valid = 0;
    	for(int l = 0, r = 0; r < str.size();)
    	{
    		//扩大窗口
    		char ch = str[r];
    		//窗口右移
    		r++;
    		
    		//进行窗口内数据的一系列更新
    		...
    		
    		
    		cout << l << " " << r << endl;
    		
    		//移动窗口
    		while()
    		{
    			//d是即将要移动出窗口的字符
    			char d = str[l];
    			//左移窗口
    			l++;
    			
    			//更新结果
                ...
    		}
    	}
    }
    

    无重复字符的最长子串

    题目链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            unordered_map<char, int> hashmap;
    
            int cnt = 0;
            for(int i = 0, j = 0; j < s.size(); j++)
            {
                hashmap[s[j]]++;
                while(hashmap[s[j]] > 1) hashmap[s[i++]]--;
                cnt = max(cnt, j - i + 1);
               
            }
            return cnt;
        }
    };
    

    最小覆盖子串

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

    class Solution {
    public:
        string minWindow(string s, string t) {
            unordered_map<char, int> need, win;
            for(int i = 0; i < t.size(); i++) need[t[i]]++;
    
            //l和r分别是在当前字符串上维护的窗口的左右两端
            int l = 0, r = 0;
            int valid = 0;
    
            //记录最小子串的起始位置和长度
            int start = 0, cnt = INT_MAX;
           
            
            while(r < s.size())
            {
                //即将进入窗口的字符
                char ch = s[r];
                //右移窗口
                r++;
    
                //进行窗口内数据的一系列更新
                if(need.count(ch))
                {
                    win[ch]++;
                    if(win[ch] == need[ch]) valid++;
                }
    
                //判断左侧窗口是否要收缩
                while(valid == need.size())
                {
                    //更新最小覆盖子串
                    if(r - l < cnt)
                    {
                        start = l;
                        cnt = r - l;
                    }
                    //向右滑动
                    char d = s[l];
                    l++;
                    if(need.count(d))
                    {
                        if(win[d] == need[d])
                            valid--;
                        win[d]--;
                    }
                }
            }
            return cnt == INT_MAX ? "" : s.substr(start, cnt);
    
    
        }
    };
    

    字符串的排列

    题目链接:https://leetcode-cn.com/problems/permutation-in-string/

    class Solution {
    public:
        bool checkInclusion(string s1, string s2) {
    
            //维护一个窗口为s1.size的窗口,判断s1中是否包含s1的所有
            unordered_map<int, int> hashmap, win;
            for(char c : s1) hashmap[c]++;
            
            int valid = 0;
            for(int l = 0, r = 0; r < s2.size();)
            {
                //扩大窗口
                char ch = s2[r];
                //窗口右移
                r++;
                
                //进行窗口内数据的一系列更新 更新判断条件valid
                //...
                if(hashmap.count(ch))
                {
                    win[ch]++;
                    if(win[ch] == hashmap[ch]) valid++;
                }
                
                cout << l << " " << r << endl;
                
                //移动窗口 满足条件了进行更新  包含那个字符
                while(r - l >= s1.size())
                {
                    if(valid == hashmap.size()) return true;
                    //d是即将要移动出窗口的字符
                    char d = s2[l];
                    //左移窗口
                    l++;
                    
                    //更新结果
                    //...
                    if(hashmap.count(d))
                    {
                        if(win[d] == hashmap[d])
                            valid--;
                        win[d]--;
                    }
                }
            }
            return false;
        }
    };
    

    找到字符串中所有字母异位词

    题目链接:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/

    class Solution {
    public:
        vector<int> findAnagrams(string s, string p) {
            vector<int> res;
    
            unordered_map<char, int> hashmap, win;
    
            for(auto ch : p) hashmap[ch]++;
    
            int valid = 0;
            for(int l = 0, r = 0; r < s.size();)
            {
                char ch = s[r];
                r++;
    
                if(hashmap.count(ch))
                {
                    win[ch]++;
                    if(win[ch] == hashmap[ch]) valid++;
                }
                cout << l <<" " << r << " " << valid << endl;
                while(r - l >= p.size())
                {
                    if(valid == hashmap.size()) res.push_back(l);
    
                    char d = s[l];
                    l++;
                    if(hashmap.count(d))
                    {
                        if(win[d] == hashmap[d]) valid--;
                        win[d]--;
                    }
                }
            }
            return res;
        }
    };
    
  • 相关阅读:
    数据库事务隔离级别+Spring 声明性事务隔离级别
    (面试题)如何查找Oracle数据库中的重复记录
    Spring提供的线程池支持--百度文库
    (面试题)输出下列程序结果(考察字符串与其他类型+连接)
    (面试)有两个木桶,一个3斤,一个5斤,水无限,要怎么样得到精确地4斤水
    (面试)涉及到继承和类加载
    (面试题)用折半查找法在一组整形数组中查找某个数据
    (面试)写出下面switch语句的输出结果
    HTML 鼠标坐标和元素坐标
    HTML5 元素属性介绍
  • 原文地址:https://www.cnblogs.com/Trevo/p/13517718.html
Copyright © 2011-2022 走看看