【LeetCode刷题之旅】滑动窗口例题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38371360/article/details/86578609

#209 Minimum Size Subarray Sum

给定一个含有 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组如果不存在符合条件的连续子数组,返回 0。

示例: 

输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。

进阶:

如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。

//时间复杂度:O(n)
//空间复杂度:O(1) 

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
    	
    	int l = 0, r = -1;	//nums[l...r]是我们的滑动窗口
		int sum = 0;
		int res = nums.size() + 1;
		
		while(l < nums.size()){
			
			if ( r+1 < nums.size() && sum < s)
				sum += nums[++r];	//r++;sum += nums[r]
			else
				sum -= nums[l++];
			
			if( sum >= s)
				res = min(res,r-l+1);				
			
		}
		if(res == nums.size()+1)
			return 0;
		return res;
        
    }
};

#003 Longest Substring Without Repeating Characters

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke"所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke"是一个子序列,不是子串。
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int freq[256] = {0};       //设置一个数组,0为没有重复,1为重复
        int l = 0, r = -1;	//滑动窗口为s[l...r] 
        int res = 0;
		
		while( l<s.size()){
			
			if( r+1 < s.size() && freq[s[r+1]] == 0){
				r++;            //如果没有重复的子串,那就继续++
				freq[s[r]]++;	//可以写成freq[s[++r]]++ 
			
			}
			else
				freq[s[l++]]--;    //移动左边界,将其在freq中的值置为0,重新划定滑动窗口
			
			res = max(res,r-l+1);
		}
		return res;
    }
};

 

#438 Find All Anagrams in a String

给定一个字符串 和一个非空字符串 p,找到 中所有是 的字母异位词的子串,返回这些子串的起始索引。

字符串只包含小写英文字母,并且字符串 和 的长度都不超过 20100。

说明:

  • 字母异位词指字母相同,但排列不同的字符串。
  • 不考虑答案输出的顺序。

如 s = "cbaebabacd"    p = "abc", 返回[0,6]

如 s = "abab"   p = "ba", 返回[0,1,2]

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        if (s.empty()) return {};           //判断是否为空
        vector<int> res, m(256, 0);
        int left = 0, right = 0, count = p.size(), n = s.size();
        for (char c : p) ++m[c];        //遍历string p
        while (right < n) {
            if (m[s[right++]]-- >= 1) --count;
            if (count == 0) res.push_back(left);
            if (right - left == p.size() && m[s[left++]]++ >= 0) ++count;
        }
        return res;
    }
};

#76 Minimum Window Substring

给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。

示例:

输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

说明:

  • 如果 S 中不存这样的子串,则返回空字符串 ""
  • 如果 S 中存在这样的子串,我们保证它是唯一的答案。
class Solution {
public:
    string minWindow(string s, string t) {
        string res = "";
        unordered_map<char, int> letterCnt;
        int left = 0, cnt = 0, minLen = INT_MAX;
        for (char c : t) ++letterCnt[c];
        for (int i = 0; i < s.size(); ++i) {
            if (--letterCnt[s[i]] >= 0) ++cnt;
            while (cnt == t.size()) {
                if (minLen > i - left + 1) {
                    minLen = i - left + 1;
                    res = s.substr(left, minLen);
                }
                if (++letterCnt[s[left]] > 0) --cnt;
                ++left;
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_38371360/article/details/86578609