這道題給定了我們一個數(shù)字,讓我們求子數(shù)組之和大于等于給定值的最小長度。
- 先來看O(n)的解法:
- 我們需要定義兩個指針left和right,分別記錄子數(shù)組的左右的邊界位置,初始都指向array[0], 然后我們讓right向右移(子序列擴(kuò)大),直到子數(shù)組和大于等于給定值或者right達(dá)到數(shù)組末尾,此時我們更新最短距離。
- 然后看看能不能得到更小的符合條件的子序列,將left像右移一位進(jìn)行嘗試,如果還是大于,繼續(xù)left右移, 如果小于或等于(因?yàn)槊總€都是正數(shù)), 說明不可能有更小的了,只能整個window右移來嘗試新機(jī)會。注意length == 1 的時候可以提前結(jié)束搜索。
代碼如下:
//
// main.cpp
// leetcode
//
// Created by YangKi on 15/11/19.
// Copyright ? 2015年 YangKi. All rights reserved.
#include<vector>
#include<algorithm>
#include<cstdio>
#include <unordered_map>
#include <cmath>
using namespace std;
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int size = (int)nums.size();
if (size == 0)
{
return 0;
}
int left = 0;
int right = 0;
int length;
int sumOfWindow = nums[0];
// 先擴(kuò)大(right 右移)
while (sumOfWindow < s)
{
right ++;
if (right > size - 1)
{
break;
}
sumOfWindow += nums[right];
}
if (right == size)
{// 說明全加一起也小于s
return 0;
}
// 否則,先確定一個窗口大小
length = right - left + 1;
// 接下來就是嘗試有沒有更小的窗口
while (right <= size -1)
{
// 嘗試縮?。╨eft 右移)
while (sumOfWindow - nums[left] >= s)
{
sumOfWindow -= nums[left];
left++;
length --;
if (length == 1)
{
return 1;
}
}
// 不能再縮小了,只能整體右移
if (right + 1 >= size)
{// 已經(jīng)不能右移了
return length;
}
sumOfWindow = sumOfWindow - nums[left] + nums[right + 1];
left ++;
right ++;
}
return length;
}
};