最大子串行問題的解,就是求乙個陣列中,從某個位置開始到某個位置結束,這段數相加得到的和是該陣列中最大的值,求這個最大值。
舉個例子:4,-3,5,-2,-1,2,6,-2這8個數的陣列中,最大的子串行的和為11,從a1到a7相加為最大值。
求解這個問題有多種方法,這裡介紹三種方法來求解該問題。
第一種也就是蠻力法,從陣列頭開始遍歷,得到所有的可能,然後乙個個進行比較,得到最大值。
int get_max(const
vector
&a)
}return max_num;
}
思想簡單,**簡單,但是其時間複雜度卻是n的平方。
第二種方法使用的就是分治法思想,使用遞迴的方式來解決問題。
我們思考最大子串行出現的位置,如果我們將整個陣列一分為二,可以發現乙個規律,那就是最大子串行只會出現在三個位置——陣列左邊,陣列右邊,或者在連線兩邊的中間位置。
只要我們能夠求出左邊的最大子串行的值,右邊最大子串行的值,以及中間部分的最大子串行的值,三者比較,最大者就是我們所需要的最大子串行的值。
陣列左邊和陣列右邊的最大值很好解決,但是跨越兩邊是什麼情況呢?
這種情況就是左邊的最大值和右邊的最大值相加就能得到我們需要的中間部分的最大值。
當然,問題肯定不是這麼簡單,這個左邊的最大值和右邊的最大值並不等於我們前面說的左邊的最大子串行和右邊的最大子串行。
最大子串行要求我們所有的數都必須是相連的,所以這種情況下的左邊最大值的子串行必須和右邊最大值的子串行相連線起來,即必須包含陣列中間的兩個數。
接著我們的開始的例子,先分成兩邊,左邊為4,-3,5,-2,左邊的最大子串行很簡單a1到a3為6,右邊為-1,2,6,-2,右邊的最大子串行a5到a7為7。
最後是中間的最大子串行,必須是包含兩邊相連的最大子串行的值相加,也就是說左邊必須包含有-2,右邊必須包含有-1,這樣,兩邊的序列才能接起來,構成子串行。左邊包含-2的最大子串行為4,a1到a4,右邊包含-1的最大子串行為a5-a7為7,兩件相加為11。
三個數進行比較,我們發現最大子串行出現在中間,為11,從a1到a7。
下面是**:
int max(int a,int b,int c)/*得到三個數的最大值
下面函式為求得中間部分的最大子串行的值。
引數s代表陣列的開始下標,left代表左邊部分最後乙個數的下標,right代表右邊第乙個數的下標,e代表陣列的最後下標.
求得的方法和第一種方法沒有什麼差別。
int middle_num(const
vector
& a,int s,int left,int right,int e)
int right_max=0;
this_max=0;
for(int i=right;i<=e;i++)//求得左邊的最大子串行(包含a[right])
return left_max+right_max;
}
/*得到最大子串行的值*/
int get_max(const
vector
& a,int s,int e)
使用遞迴的思想來解決問題,思想有點發雜,**相比第一種方法多了很多,但是它的時間複雜度確確實實比第一種方法好,為o(nlogn),降低了很多。
第三種方法最為簡單,時間複雜度僅僅只有o(n),下面為**:
int get_max(const
vector
& a)
return max_num;
}
這種方法最為簡單,**更是簡單。
這種方法可不可以,還有思想是什麼,請自己去想。
最大子串行和問題的解
問題 有數n1,n2,ns。求乙個連續的子串行,這個序列的和最大。這個問題有o n 3 o n 2 o n lgn 以及o n 時間複雜度的解法。下面主要說下o n lgn 和o n 的解法。1.o n lgn 是採用分治的思想。前半部 後半部 4 3 5 2 1 2 6 2 最大子串行的和可能出現...
最大子串行問題
問題描述 輸入一組整數,求出這組數字子串行和中最大值。也就是只要求出最大子串行的和,不必求出最大的那個序列。例如 序列 2 11 4 13 5 2,則最大子串行和為20。複雜度為o n 2 的演算法 include include int maxsubseqsum const int a,int n...
最大子串行問題
現在我們將敘述兩個演算法來求解最大子串行和問題 include int maxsubsequencesum int a,int n int main printf max d maxsubsequencesum a,15 return0 int maxsubsequencesum int a 15 ...