滑动窗口思想

在解决子串或者子数组(要求结果连续的),一般可以想一想活动窗口

滑动窗口掌握的核心是:双指针

右指针右移:目的是找到满足符合条件的
左指针右移:两个目的(压缩+更新+破而后立),首先左移到满足先前那个状态的最小情况(压缩),就可以做更新操作(更新),之后再移动破除当前状态寻找下一个满足条件的状态(破而后立)

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

输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

unordered_set 存储出现的字符

在添加前寻找是否之前存在过

如果存在,左指针向右移动,我们从哈希集合中移除一个字符,
如果不存在,右指针向右移动,我们往哈希集合中添加一个字符

右指针右移:目的是找到满足符合条件的,符合条件的也就是尽可能最长,什么时候最长,也就是哈希表中存在过
左指针右移:两个目的(压缩+更新+破而后立),此题无需压缩因为当前每个都是出现一个,压缩就不符合了(压缩),然后可以做更新操作(更新),之后再移动破除当前状态寻找下一个满足条件的状态(破而后立)

int lengthOfLongestSubstring(string s) {
	if (s.size() == 0) return 0;
	unordered_set<char> lookup;
	int maxStr = 0;
	int left = 0;
	for (int i = 0; i < s.size(); i++) {
		// 破
		while (lookup.find(s[i]) != lookup.end()) {
			lookup.erase(s[left]);
			left++;
		}
		//更新
		maxStr = max(maxStr, i - left + 1);
		//右移
		lookup.insert(s[i]);
	}
	return maxStr;

}

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”

class Solution {
public:
   string minWindow(string s, string t) {
	int index = 0;
	int res = INT_MAX;
	int start = 0;
	vector<int> need(128, 0);
	for (int i = 0; i < t.length(); i++) {
		need[t[i]]++;
	}
	int cur = t.length();
	for (int i = 0; i < s.length(); i++) {
	   //右移
		if (need[s[i]] > 0) 
			cur--;
		need[s[i]]--;
		// 直到满足条件
		if (cur == 0) {
		   // 压缩
			while (need[s[start]]<0 && start < i) {
				need[s[start]]++;
				start++;

			}
			// 更新
			if (i - start + 1 < res) {
				res = i - start + 1;
				index = start;
			}

			//破
			need[s[start]]++;
			cur++;
			start++;
		}


	}
	return res==INT_MAX ? "" : s.substr(index, res);
}
	
};

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

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

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
     
        int start=0;
        int size=INT_MAX;
        int ans=0;
        for(int i=0;i<nums.size();i++){
            
            // 右移
            ans+=nums[i];
            //直到满足条件
            if(ans>=target){
               // 压缩
                while(ans-nums[start]>=target&&start<i){
                   
                    ans-=nums[start];
                    start++;
                    
                }
                // 更新
                if(size>i-start+1){
                   size=i-start+1;
              
                }

                //破
                 ans-=nums[start];
                 start++;
                 
            }




        }
        return size==INT_MAX? 0:size;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yilyil

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值