【算法】一篇文章带你狂刷双指针的滑动窗口

借助双指针实现滑动窗口,虽然遇到新的题还是不会,但我还是要写,狠狠感动自己

3.无重复字符的最长子串

【算法】一篇文章带你狂刷双指针的滑动窗口_第1张图片

算法思路

(1)果 [ l , r ] [l , r] [l,r]存在重复子串,那么 [ l , r , r + 1 , r + 2..... ] [l, r, r + 1, r + 2.....] [l,r,r+1,r+2.....]也存在重复子串;

(2)如果 [ l , r ] [l, r] [l,r]不存在重复子串,那么 [ l , l + 1 , l + 2 , . . . , r ] [l, l + 1, l+ 2, ..., r] [l,l+1,l+2,...,r]也不存在重复子串。

那么由此就可以构造滑动窗口啦!

while (l < r && mp[s[r]] > 1) {
    mp[s[l]]--;
    l ++;
}

这部分代码是说,我们考虑(1)情况,对于新进窗口的 r 来说,如果右边加上他,导致存在重复子串,那么我们就需要处理窗口左边的字符,也就是把 l++ ;

code

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int ans = 0;
        map<char, int> mp;
        for (int l = 0, r = 0; r < s.size(); r ++) {
             mp[s[r]] ++;
            while (l < r && mp[s[r]] > 1) {
                mp[s[l]]--;
                l ++;
            }
            ans = max(ans, r - l + 1);
        }
        return ans;
    }
};

209. 长度最小的子数组

【算法】一篇文章带你狂刷双指针的滑动窗口_第2张图片

算法思路

直接套模板(不是)

(1)果 [ l , r ] [l , r] [l,r]的元素和大于target,那么 [ l , r , r + 1 , r + 2..... ] [l, r, r + 1, r + 2.....] [l,r,r+1,r+2.....]的元素的和必定大于target

(2)如果 [ l , r ] [l, r] [l,r]的元素和小于target,那么 [ l , l + 1 , l + 2 , . . . , r ] [l, l + 1, l+ 2, ..., r] [l,l+1,l+2,...,r]的元素和也必定小于target

所以只需要去长度最小的 ans 即可

code

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int sum = 0, ans = 1e9;
        for (int l = 0, r = 0; r < nums.size(); r++) {
            sum += nums[r];
            while (l <= r && sum >= target) {
                ans = min(ans, r - l + 1);
                sum -= nums[l];
                l++;
            }
        }
        if (ans != 1e9)
            return ans;
        else
            return 0;
    }
};

713. 乘积小于 K 的子数组

【算法】一篇文章带你狂刷双指针的滑动窗口_第3张图片

算法思路

跟上一题差不多

code

class Solution {
public:
    int numSubarrayProductLessThanK(vector<int>& nums, int k) {
        int sum = 1, ans = 0;
        for (int l = 0, r = 0; r < nums.size(); r ++) {
            sum *= nums[r];
            while (l < r && sum >= k) {    
                sum /= nums[l++];
            }
            if (sum < k)
                ans += r - l + 1;
        }
        return ans;
    }
};

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

【算法】一篇文章带你狂刷双指针的滑动窗口_第4张图片

算法思路

这里我们就需要转化一下我们的思维了,我们可以用哈希表 来统计p的字符频率,在 s 上维护一个和 p 长度相同的窗口,比较窗口内字符的评率和 p 的字符频率,当频率匹配时记录起始索引。

那么就可以继续模板:

(1)果 [ l , r ] [l , r] [l,r]中存在某个字符数量大于 p 中字符数量,那么 [ l , r , r + 1 , r + 2..... ] [l, r, r + 1, r + 2.....] [l,r,r+1,r+2.....]也一定存在某个字符的数量大于p中字符数量;

(2)如果 [ l , r ] [l, r] [l,r]的每个字符的数量都小于或等于p中的字符数量,那么 [ l , l + 1 , l + 2 , . . . , r ] [l, l + 1, l+ 2, ..., r] [l,l+1,l+2,...,r]也成立。

code

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        unordered_map<char, int> mp;
        for (int i = 0; i < p.size(); i  ++ ) {
            mp[p[i]] ++;
        }
        vector<int> res;
        for (int l = 0, r = 0; r < s.size(); r ++) {
            mp[s[r]] --;
            while (l <= r && mp[s[r]] < 0) {
                mp[s[l]] ++;
                l ++;
            }
            if (r - l + 1 == p.size()) {
                res.push_back(l);
            }
        }
        return res;
    }
};
     }
        if (r - l + 1 == p.size()) {
            res.push_back(l);
        }
    }
    return res;
}

};


你可能感兴趣的:(#,算法题解-高级数据结构,算法,数据结构,C++)