題目:輸入乙個整型陣列,陣列裡有正數也有負數。陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間負責度為o(n)。看到這個題目,我們首先想到的是求出這個整型陣列所有連續子陣列的和,長度為n的陣列一共有 n(n+2)/2個子陣列,因此要求出這些連續子陣列的和最快也需要o(n^2)的時間複雜度。但是題目要求的o(n)的時間複雜度,因此上述思路不能解決問題。
看到o(n)時間複雜度,我們就應該能夠想到我們只能對整個陣列進行一次掃瞄,在掃瞄過程中求出最大連續子串行和以及子串行的起點和終點位置。假如輸入陣列為,我們嘗試從頭到尾累加其中的正數,初始化和為0,第一步加上1,此時和為1,第二步加上-2,此時和為-1,第三步加上3,此時我們發現-1+3=2,最大和2反而比3乙個單獨的整數小,這是因為3加上了乙個負數,發現這個規律以後我們就重新作出累加條件:如果當前和為負數,那麼就放棄前面的累加和,從陣列中的下乙個數再開始計數。
**例項:
view code
#include#include經過@yu's 技術生涯 測試,發現我上面的**確實存在問題,現在做了如下修改:using
namespace
std;
//求最大連續子串行和
int findgreatestsumofsubarray(int arry,int
len)
else
currsum+=arry[i];//
如果當前最大和不為負數則加上當前數
if(currsum>greatestsum)//
如果當前最大和大於全域性最大和,則修改全域性最大和
}cout
<
最大子串行位置:
"return
greatestsum;
}void
main()
;
int len=sizeof(arry)/sizeof(int
);
//cout
cout
<
最大子串行和:
"system(
"pause");
}
1.新增了乙個遍歷用於儲存遍歷陣列中發現的最大和的起始,原來的start和end只用於儲存真是的開始於結尾。
2.當currsum<0的時候,我們只讓p值為最大和子陣列的開始
3.在最後判斷currsum>greatestsum的時候,只有當currsum>greatestsum成立,才讓start=p,否則就表明以p開頭的子陣列最大和不是最大的。
示例**如下:
view code
#include#include如果用函式f(i)表示以第i個數字結尾的子陣列的最大和,那麼我們需要求出max(f[0...n])。我們可以給出如下遞迴公式求f(i)using
namespace
std;
//求最大連續子串行和
int findgreatestsumofsubarray(int arry,int
len)
else
currsum+=arry[i];//
如果當前最大和不為負數則加上當前數
if(currsum>greatestsum)//
如果當前最大和大於全域性最大和,則修改全域性最大和
}cout
<
最大子串行位置:
"return
greatestsum;
}void
main()
;int arry=;
int len=sizeof(arry)/sizeof(int
);
//cout
cout
<
最大子串行和:
"system(
"pause");
}
這個公式的意義:
當以第(i-1)個數字為結尾的子陣列中所有數字的和f(i-1)小於0時,如果把這個負數和第i個數相加,得到的結果反而不第i個數本身還要小,所以這種情況下最大子陣列和是第i個數本身。
如果以第(i-1)個數字為結尾的子陣列中所有數字的和f(i-1)大於0,與第i個數累加就得到了以第i個數結尾的子陣列中所有數字的和。
view code
//其實上述兩種方法的實現方式非常相似,只是解體思路不同而已。通常我們會使用遞迴的方式分析動態規劃的問題,但是最終都會基於迴圈去寫**。在動態規劃方法中建立了乙個陣列c用於儲存中間結果,而第一種方法中只需要乙個臨時變數currsum.使用動態規劃求最大連續子陣列和
int findgreatestsumofsubarray2(int arry,int len,int
c)
else
c[i]=arry[i]+c[i-1
];
if(c[i]>maxgreatsum)
}//輸出c[i]
for(int i=0;i)
cout
cout
<
cout
<
最大子串行位置:
"return
maxgreatsum;
}
面試題31 連續子陣列的最大和
題目 輸入乙個整形陣列,陣列裡有正數也有負數,陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間複雜度為o n 例如,輸入陣列 1,2,3,10,4,7,2,5 和最大的子陣列微3,10,4,7,2,因此輸出該子陣列的和18 思路 1,分析陣列規律 初始化和0,第一哥數字1...
面試題31 連續子陣列的最大和
面試題31 連續子陣列的最大和 hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了 在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如 連續子向量...
面試題31連續子陣列的最大和
題目 輸入乙個整型陣列,陣列裡有正數也有負數。陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間負責度為o n 看到這個題目,我們首先想到的是求出這個整型陣列所有連續子陣列的和,長度為n的陣列一共有 n n 2 2個子陣列,因此要求出這些連續子陣列的和最快也需要o n 2 ...