標籤:
最長子序列和的問題非常easy:
就是一個數組,求出當中當中連續的某一段和,而這一段和是全部的連續段和的最大的值。求出這個值。
先說複雜度最高的:O(n3)
直接上代碼,非常easy的:
//// main.cpp// SumSequence//// Created by Alps on 14-7-23.// Copyright (c) 2014年 chen. All rights reserved.//#include <iostream>using namespace std;int MaxSubsequenceSum(const int A[], int N){ int ThisSum, MaxSum, i, j, k; MaxSum = 0; for(i = 0; i < N; i++){ for(j = i; j < N; j++){ ThisSum = 0; for (k = i; k < j; k++) { ThisSum += A[k]; } MaxSum = ThisSum > MaxSum ? ThisSum: MaxSum; } } return MaxSum;}int main(int argc, const char * argv[]){ int A[] = {1, 2, -5, 2, 5, 1, 8, -4}; int N = sizeof(A)/sizeof(int);// printf("%d\n",N); int MaxSum = MaxSubsequenceSum(A, N); printf("%d\n",MaxSum); return 0;}
這個事實上非常easy,第一層for迴圈是i從頭開始遍曆。第二層for是j從i遍曆到尾。第三層就是算i到j的這一段的和。
時間複雜度是O(n3).
以下說一個O(n2)的:
代碼例如以下:
//// main.cpp// SumSequencen2//// Created by Alps on 14-7-23.// Copyright (c) 2014年 chen. All rights reserved.//#include <iostream>using namespace std;int MaxSubSequenceSum(const int A[], int N){ int MaxSum, ThisSum, i, j; MaxSum = 0; for (i = 0; i < N; i++) { ThisSum = 0; for (j = i; j < N; j++) { ThisSum += A[j]; MaxSum = MaxSum > ThisSum ? MaxSum : ThisSum; } } return MaxSum;}int main(int argc, const char * argv[]){ int A[] = {1, 2, -5, 2, 5, 1, 8, -4}; int N = sizeof(A)/sizeof(int); // printf("%d\n",N); int MaxSum = MaxSubSequenceSum(A, N); printf("%d\n",MaxSum); return 0;}這個也比較好理解,第一層迴圈就是i從頭到尾遍曆,第二層迴圈是j從i遍曆到尾,在遍曆過程中不斷檢測ThisSum的大小,取Max(ThisSum, MaxSum)的數,並賦值給MaxSum,這樣就能夠知道MaxSum是多少了~
另一個方法複雜度是O(nlogn)可是這個演算法比較麻煩,代碼也比較麻煩,我這裡沒有寫~想學的能夠去《資料結構與演算法分析》來學習。
這裡有一個O(n)層級的演算法來解決問題!!!:請看代碼:
//// main.cpp// SumSequencen//// Created by Alps on 14-7-23.// Copyright (c) 2014年 chen. All rights reserved.//#include <iostream>using namespace std;int MaxSubSequenceSum(const int A[], int N){ int MaxSum, ThisSum, i; MaxSum = A[0]; ThisSum = 0; for (i = 0; i < N; i++) { ThisSum += A[i]; MaxSum = ThisSum > MaxSum ? ThisSum: MaxSum; if (ThisSum < 0) { ThisSum = 0; continue; } } return MaxSum;}int main(int argc, const char * argv[]){ int A[] = {1, 2, -5, 2, 5, 1, 8, -4}; int N = sizeof(A)/sizeof(int); // printf("%d\n",N); int MaxSum = MaxSubSequenceSum(A, N); printf("%d\n",MaxSum); return 0;}
O(n)層級的這類演算法算是比較完美的演算法了。我對這個演算法的理解就是,在一個數組裡,有非常多非常多段,這些段都有一個和,最小的段是一個元素,而最大的序列和肯定是一個段,或者是兩個段的和,和就是加上一個正數就變大,所以當一個段是負數的時候,我就直接拋棄掉了~(除非全部都是負數,就找一個最大的。)
所以就有了上面的演算法。。不懂的請留言~
演算法-最長子序列和C/C++實現(三個複雜度)