每天進步一點點 求最大子串行和問題

2021-06-23 04:19:31 字數 1831 閱讀 6199

假設有如下整數陣列 -10 5 0 8 -1 10 -10 100 -1 求其最大的子串行和。從該陣列我們可以知道其子序列和最大的序列為5 0 8 -1 10 -10 100且等於112。(為方便起見,如果陣列全是負數則最大和為0)

處理這個問題,我們可以有如下四種方法:

方法一:時間複雜度為o(n^3)

int maxsubsum1(const std::vector& vec)

if (sum > max) }

}return max; }

該方法是求出所有子串行的和,然後在得出最大的和。

方法二:時間複雜度為o(n^2)

int maxsubsum2(const std::vector& vec)

} }

return max; }

因為後一子串行的和為前面序列和加上後面一元素,所以在前面子串行和已被求出的情況下可以少一次迴圈

方法三:時間複雜度為o(n log(n))

int maxsubsum3(const std::vector& vec, int left, int right)

else  }

int center = (right + left) / 2;

int left_max_sum = maxsubsum3(vec, left, center);

int right_max_sum = maxsubsum3(vec, center + 1, right);

int left_sum = 0;

int left_max = 0;

for (int i = center; i >= left; --i) }

int right_sum = 0;

int right_max = 0;

for (int i = center + 1; i <= right; ++i) }

return std::max(std::max(left_max_sum, right_max_sum), (right_max + left_max)); }

該方法是左右劃分陣列,然後遞迴分別求出每個被劃分陣列的最大和

方法四:時間複雜度為o(n)

int maxsubsum4(const std::vector& vec)

else if (sum < 0) }

return max; }

這種方法是最為高效的,一次掃瞄陣列就能求出,具有這種特性的演算法叫作聯機演算法(on-line algorithm)

#include #include #include int main(int argc, char const *argv)

std::vectorvec;

vec.reserve(argc - 1);

for (int i = 0; i < argc - 1; ++i)

std::cout << maxsubsum1(vec) << std::endl;

std::cout << maxsubsum2(vec) << std::endl;

std::cout << maxsubsum3(vec, 0, vec.size() - 1) << std::endl;

std::cout << maxsubsum4(vec) << std::endl;

return 0;

}

編譯g++ -std=c++11 main.cc -o sum

執行./sum 

-10 5 0 8 -1 10 -10 100 -1

輸出如下:

112112

112112 

每天進步一點點

很多朋友總喜歡問 成功靠什麼?其實,成功很難單一的歸納為靠什麼條件,如果一定要回答,只能從某種意義上說 很多人的成功就是靠他們每天比別人 多做一點點 正如古人有云 業精於勤,荒於嬉。這裡所說的勤,也就是比別人多做一點點,即付出多一點的勞動和努力。不要小看這一點點,又如古語說 集腋成裘,積沙成丘。如果...

每天進步一點點

在模組化程式設計時,在子模組中宣告變數 例如unsigned char aa 不需要在標頭檔案中宣告 要在主函式中呼叫,要寫成 extern unsigned char aa 而不能寫成 extern aa 寫成extern aa 則無法改變aa的值。2014年9月22日 21 12 00 品質因數...

每天進步一點點(一)

最近接了第乙個商業專案,一人獨立完成從前台到後台,做了有幾天的時間,每天進步一點點,把每天看到的學到的記錄下來,以後也堅持。後台繼續用自己的extjs老本行,因為相比其他js庫,extjs用的比較熟,現成的 也有所以開發起來也比較容易,今天學到了兩個ext的新東西。一 ext和後台進行互動大部分用的...