長度最小的連續子數組

長度最小的連續子數組

問題描述

給定一個含有 n 個正整數的數組和一個正整數 s ,找出該數組中滿足其和 ≥ s 的長度最小的連續子數組,並返回其長度。如果不存在符合條件的連續子數組,返回 0。
示例:
輸入: s = 7, nums = [2,3,1,2,4,3]
輸出: 2
解釋: 子數組 [4,3] 是該條件下的長度最小的連續子數組。

問題解決方案

暴力求解

首先這道題最明顯能想到的就是暴力求解,兩個for循環,第一個記錄開始的索引,第二個記錄當大於等於正整數s時的末尾索引,當得到的連續子數組的總和≥s且長度小於最小值時,更新最小值。

void function(int n, int s, int nums[]) {
    int min = n + 1;
    for (int i = 0; i < n; i++) {
        int length = 1;
        int sum = nums[i];
        for (int j = i + 1; j < n; j++) {
            length++;
            if (sum + nums[j] >= s && min > length) {
                min = length;
                break;
            } else {
                sum += nums[j];
            }
        }
    }
    if (min == n + 1) {
        cout << "min = 0" << endl;
    } else {
        cout << "min = " << min << endl;
    }
}

顯而易見,時間複雜度在O(n^2)量級上;

使用隊列

該方法定義兩個指針,首指針和尾指針,也可以看作是數組的下標索引(high表示尾指針,對應大的下標索引值;low表示首指針,對應小的索引值。nums[low]~nums[high])。解決的原則是一開始默認爲0,當sum(子數組的總和)小於s時,high向後移動一位(high++)。當sum大於等於s時,判斷當前的長度,如果長度小於最小值,更新最小值,然後low向後移動一位(low++)。直到high跑出數組外,也就是(high>=n)



void function2(int s, int n, int nums[]) {
    int min = n + 1;
    int high = 0, low = 0, sum = 0;
    while (high < n) {
        sum += nums[high++];
        while (sum >= s) {
            if (high - low < min)
                min = high - low;
            sum -= nums[low++];
        }
    }
    cout << "min = " << min << endl;
}

時間複雜度爲O(2*n)

完整代碼:

void function(int n, int s, int nums[]) {
    int min = n + 1;
    for (int i = 0; i < n; i++) {
        int length = 1;
        int sum = nums[i];
        for (int j = i + 1; j < n; j++) {
            length++;
            if (sum + nums[j] >= s && min > length) {
                min = length;
                break;
            } else {
                sum += nums[j];
            }
        }
    }
    if (min == n + 1) {
        cout << "min = 0" << endl;
    } else {
        cout << "min = " << min << endl;
    }
}

void function2(int s, int n, int nums[]) {
    int min = n + 1;
    int high = 0, low = 0, sum = 0;
    while (high < n) {
        sum += nums[high++];
        while (sum >= s) {
            if (high - low < min)
                min = high - low;
            sum -= nums[low++];
        }
    }
    cout << "min = " << min << endl;
}

void function3(int s,int n,int nums[]){
    int min = n+1;
    int high=0, low =0,sum = 0;
    while(high < n){
        s-=nums[high++];
        while(s<=0){
            if(min > high - low){
                min = high -low;
            }
            s+=nums[low++];
        }
    }
    cout << "min = " << min << endl;
}


int main() {
    int n, s;
    cin >> n >> s;
    int nums[n];
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }
    function(s,n,nums);
    function2(s,n,nums);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章