題目
求子數組的最大和
題目描述:
輸入一個整形數組,數組裏有正數也有負數。
數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個和。
求所有子數組的和的最大值。要求時間複雜度爲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;
}