题目要求找到长度最小的子串,使得字串和大于等于S
既然是要长度最小,那我们就可以从长度为1开始遍历到长度为N
,我们需要遍历图片说明次 ,当N非常大的时候耗时会特别长,所以可以稍微优化一下(双指针/尺取法)。

如果是按长度从1到N遍历,那么我们每次都要从子串的头到尾重新计算一次子串和,对此我们可以做出这样的优化:
按数组元素的位置遍历,从第一个元素开始,从长度为1不断修改子串的长度,直到子串和刚好大于等于S,再从第二个元素开始,继续往下遍历

图片说明

#include <iostream>
#include <vector>

using namespace std;

vector<int> nums;   //输入的数字序列
int main() {
    int t;  // number of test cases
    int N, S;
    cin >> t;
    while (t-- > 0) {
        nums.clear();
        int temp;
        int minLength = 1e5;    //满足题意的最小长度
        cin >> N >> S;
        for (int i = 0; i < N; ++i) {
            cin >> temp;
            nums.push_back(temp);
        }

        int i = 0, j = 0, sum = nums[0], length = 1;    //用于对数组的遍历
        if (nums[0] >= S) {
            cout << 1 << endl;
            continue;
        }
        //length用于记录当前子串长度
        while (j < N && i <= j) {
            if (sum < S) {
                j++;
                sum += nums[j];
                length++;
            } else {
                if (length < minLength)minLength = length;
                sum -= nums[i];
                i++;
                length--;
            }
        }
        //没有答案则输出0
        if (minLength == 100000)cout << 0 << endl;
        else cout << minLength << endl;
    }
}