题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
解题思路:
使用双指针法,也可以叫滑动窗口法。
我的理解是定义一个指向下标的指针 i、一个指向元素的指针 j,其初始值都为0,
i 是滑动窗口的起始端,j 是滑动窗口的结束端
窗口就是满足其和 ≥ target 的长度最小的连续子数组。
j自增,把 i 到 j 的元素相加,当其和sum大于target 时,i 增,窗口向前移动。直到把数组遍历完,得到 i 到 j 的个数,也就是长度最小的子数组。
题解
示例:
#include<iostream>
#include<vector> //包含vector的头文件
using namespace std;
int MinlenArray(vector<int>nums,int val)
{
int i = 0;
int len = 0; //窗口长度
int result = INT32_MAX; //窗口最小长度
int sum = 0;
for(int j = 0;j < nums.size();j++)
{
sum += nums[j]; //j 自增求和,看元素是否大于目标值
while(sum >= val) //如果大于目标值,则取其长度,i 窗口起始端向前移动
{
len = (j-i+1);
result = result < len ? result : len;
sum -= nums[i++];
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return (result == INT32_MAX ? 0 : result);
}
int main()
{
vector<int> V = {2,5,3,4,6,1,2,6}; //假定输入的数组为V,目标值s
int s = 15;
int ret = MinlenArray(V,s);
cout << ret << endl;
}
运行结果:
总结
双指针法在数组的运用中还是很广泛和灵活的,需要好好掌握!