双指针(二)

4.同向双指针--滑动窗口

在上一篇博客双指针常用方法_绿风天空的博客-CSDN博客中,写到了同方向双指针快慢指针的用法,这一篇写另一个用法:滑动窗口。

力扣https://leetcode.cn/problems/minimum-window-substring/题目中要找满足包含满足条件的最小子串,所以可以用左右两个指针,右指针保证满足条件(包含字符串t的全部字符),左指针保证是最小子串。左右指针之间的范围就是滑动窗口。

先用长度128的两个vector记录字符串t的出现字符和出现频次。

接着在字符串s中从头开始移动右指针,每当滑动窗口中包含了字符串t的全部字符,就开始移动左指针,缩小滑动窗口范围。当然这可能会导致滑动窗口无法包含字符串t的全部字符,所以继续移动右指针,直至满足条件。

每次滑动窗口包含字符串t的全部字符都记录下最小长度,当右指针遍历完成时,就可以获得满足条件的最小子串。

代码:

class Solution {
public:
    string minWindow(string s, string t) {
        int m = s.size(), n = t.size();
        vector<int> record(128,0);
        vector<bool> flag(128,false);

        for(auto c: t){
            flag[c] = true;
            record[c]++;
        }

        int k=0, left = 0,  minLen = m +1, minLeft;
        for(int right=0;right<m;right++){
            if(flag[s[right]]){
                if(--record[s[right]] >=0 ){
                    k++;
                }

            }

            while(k==n){
                if((right-left+1)<minLen){
                    minLen = right-left+1;
                    minLeft = left;
                }
                if(flag[s[left]] && ++record[s[left]]>0 ){
                   
                    k--;
                }
                left++;
            }
        }

        return minLen==m+1?"":s.substr(minLeft,minLen);
    }
};

5.更多练习题

力扣https://leetcode.cn/problems/longest-word-in-dictionary-through-deleting/这题先对字典排序,再依次遍历字典,用两个指针分别指向s和字典内字符串。

class Solution {
public:
    string findLongestWord(string s, vector<string>& dictionary) {
        sort(dictionary.begin(), dictionary.end(), 
        [&](string& a, string& b){
            if(a.size()==b.size()){
                return a<b;
            }
            return a.size() > b.size();
        }
        );

        for(auto d :dictionary){
            if(judge(s,d)){
                return d;
            }
        }

        return "";
    }

    bool judge(string s, string d){
        int m = s.size(), n = d.size();
        int i = 0, j = 0;
        while(i<m && j<n){
            if(s[i]==d[j]){
                j++;
            }
            i++;
        }
        return j==n;
    }


};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值