目錄
問題描述:
1、窮舉法,複雜度o(n^3)
2、窮舉法改進,複雜度o(n^2)
3、分治法,複雜度o(nlgn)
4、聯機演算法,複雜度o(n)
輸入乙個數值陣列,確定具有最大和的連續子串行
vectora;用來儲存整個序列
maxsum記錄最大連續子串行的和
left,right記錄該序列的左右元素的下標;
將所有可能的連續子串行全部算一遍
int maxsum = 0, temp = 0, i = 0, j = 0, k = 0, left, right;
for (i = 0; i < a.size(); i++)
}}
用連續子串行[i,j]的和求連續子串行[i,j+1](若存在)的和
int maxsum = 0, temp, i, j, left, right;
for (i = 0; i < a.size(); i++)
}}
可知:最大子串行和的位置存在三種情況:1、完全在左半部分;2、完全在右半部分;3、跨越左右兩部分。
所以分別求出左、右半部分的最大子串行和、以及跨越左右兩部分的最大子串行和,三者中取最大即可
求mid_index=(left+right)/2;
求max1=遞迴left~mid_index
求max2=遞迴mid_index~right
求max3=左半部分最大和(包含其最後乙個元素)+右半部分最大和(包含其第乙個元素)
return max;
觸底:子串行長度為1,返回該數
已知三種情況下最大連續子列,求整個區間內這三者的最大值。
int* maxsumrec(const vector& a, int left, int right)
else
delete x, y;
//接下來求解第三種情況
int maxleftsum = a[center], maxrightsum = a[center + 1], temp = 0;
int i, j, l, r;
//左半部分最大和(包含其最後乙個元素)
for (i = j = center ; i >= left; i--) }
l = j;
//右半部分最大和(包含其第乙個元素)
temp = 0;
for (i = j = center + 1; i <= right; i++) }
r = j;
temp = maxleftsum + maxrightsum;
if (max[0] < temp || (max[0] == temp && ((max[1] > l) || max[2] < r)))//包含左零
return max;
}
聯機演算法:在任意時刻對要操作的資料唯讀入(掃瞄)一次,一旦被讀入並處理,它就不需要在被記憶了。而在此處理過程中演算法能對它已經讀入的資料立即給出相應子串行問題的正確答案。
容易想通:最大子串行的首位不可能是負數——因為負數只能拉低總和,不能增加總和,還不如捨棄
推廣:任何負的子串行不可能是最優子串行的字首
假設已知以位置i-1為結尾的最大子串行和b[i-1],對於以位置i為結尾的最大連續子串行和b[i]
綜上b[i]=max( b[i-1]+a[i],a[i] )
然後只需要令b[0]=a[0],maxsum=a[0],然後從一開始按上述規則遍歷求b[i],並用maxsum記錄下最大的b[i]即可。
int* maxsubsum(const vector& a)
if (thissum > maxsum[0])
}return maxsum;
}
最大連續子串行和
最大連續子串行和問題是個很老的面試題了,最佳的解法是o n 複雜度,當然其中的一些小的地方還是有些值得注意的地方的。這裡還是總結三種常見的解法,重點關注最後一種o n 的解法即可。需要注意的是有些題目中的最大連續子串行和如果為負,則返回0 而本題目中的最大連續子串行和並不返回0,如果是全為負數,則返...
最大連續子串行和
求最大連續子串行和 分析 用乙個陣列存入輸入的數字。用乙個變數temp從0開始往後加,存放累計的和,用sum變數存放出現過的最大和。當temp遇到負數會減小,但不能初始化為0重新累計,因為後面還有可能出現正數,和會比前面sum大的情況。只有當temp遇到負數減到小於0時,temp初始化為0重新開始加...
最大連續子串行和
include include include include include include include include include include using namespace std typedef long long ll define pi 3.1415926535897932 ...