求連續子數組的最大和

題目

求子數組的最大和

題目描述:
輸入一個整形數組,數組裏有正數也有負數。
數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個和。
求所有子數組的和的最大值。要求時間複雜度爲O(n)。

例如輸入的數組爲:1 -1 1 1 -1
因此輸出爲該子數組的和爲:2

解答

方法1:掃描法

掃描整個數組,計算所有的可能結果,然後得到最大的結果爲返回值。
這種實現方式,當數組足夠大時,效率極差。

C++程序代碼實現

int getMaxSubInt(int arr[], int n){
    int maxSum=0;
    for(int j=0; j<n; j++){
        for(int k=0; k<n; k++){
            int temp = 0;
            for(int l=j; l<=k; l++){
                temp = temp + arr[l];
            }
            if(temp > maxSum){
                maxSum = temp;
            }
        }
    }
    return maxSum;
}

方法2:動態規劃

設sum[i]爲以第i個元素結尾且和最大的連續子數組。假設對於元素i,所有以它前面的元素結尾的子數組的長度都已經求得,那麼以第i個元素結尾且和最大的連續子數組實際上,要麼是以第i-1個元素結尾且和最大的連續子數組加上這個元素,要麼是隻包含第i個元素,即sum[i] = max(sum[i-1] + a[i], a[i])。可以通過判斷sum[i-1] + a[i]是否大於a[i]來做選擇,而這實際上等價於判斷sum[i-1]是否大於0。由於每次運算只需要前一次的結果,因此並不需要像普通的動態規劃那樣保留之前所有的計算結果,只需要保留上一次的即可,因此算法的時間和空間複雜度都很小。

C++程序代碼實現

int getMaxSubSum(int arr[], int n){
    maxSum = arr[0];
    sum = arr[0];
    for(int i=1; i<n; i++){
        if( sum > 0){
            sum += arr[i];
        }else{
            sum = arr[i];
        }
        if(sum > maxSum){
            maxSum = sum;
        }
    }
    return maxSum;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章