滑动窗口问题---双指针解法

滑动窗口问题:

滑动窗口这类问题一般需要用到双指针来进行求解,一般都是基于字符串和数组的。

  1. 给两个字符串,一长一短,问其中短的是否在长的中满足一 定的条件存在,例如:求短的字符串在长的字符串中出现的所有位置

  2. 给一个字符串或者数组,问这个字符串的子串或者子数组是否满足一 定的条件。例如:

  • 含有少于k个不同字符的最长子串

  • 所有字符都只出现一次的最长子串

除此之外。还有一些其他的问法。但是不变的是。这类题目脱离不开主串(主数组)和子串(子数组)的关系,要求的时间复杂度往往是0(n),空间复杂度往往是常数级的。


题目描述:
给定一个含有n个整数的数组和一个正整数s,找出数组中的子串满足其和>=s的最小连续子数组的长度。

例如:
给的数组为2,3,1,2,4,3,s为7,因此输出的值就应该为2,即4+3


如何来求解这道题呢?

第一种方法就是暴力解法,循环遍历每个数,然后和后边的数相加,判断是否大于s,在求最小值,时间复杂度为O(N^2),对于一般题目显然会超时,因此这里就需要使用滑动窗口来解决


滑动窗口主要用来处理连续问题。比如题目求解连续子串xxx,连续子数组xxx".就应该可以想到滑动窗口。

从类型上说主要有:

  • 固定窗口大小

  • 窗口大小不固定,求解最大的满足条件的窗口

  • 窗口大小不固定,求解最小的满足条件的窗口

窗口大小不固定:

对于可变窗口,我们同样固定初始化左右指针 l 和r,分别表示的窗口的左右顶点。我们需要保证:

  1. l和r都初始化为1

  2. r指针移动1步

  3. 判断窗口内的连续元素是否满足题目限定的条件

  • 如果满足,再判断是否需要更新最优解,如果需要则更新最优解。井尝试通过移动 I 指针缩小窗口大小。
  • 循环执行上一步, 如果不满足,则继续将r指针加一。

时间复杂度: 0(n)


下边是代码:

#include <iostream>
using namespace std;
#define inf 0x3f3f3f3f
int n,s,ans;
int a[1005];

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	cin>>s;//找出和>=s的最小连续子数组的长度 
	int l=1;//左指针 
	int r=1;//右指针 
	int tot=0;//记录子数组的和 
	ans=inf;
	for(r=1;r<=n;r++)
	{
		tot+=a[r];
		while(tot>=s)
		{
			ans=min(ans,r-l+1);//r-l+1为子数组长度
			tot-=a[l];
			l+=1;
		}
	}
	cout<<ans<<endl;
		
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值