目錄
-
最大子序列的概念
在計算機科學中,最大子數列問題的目標是在數列的一維方向找到一個連續的子數列,使該子數列的和最大。例如,對一個數列 −2, 1, −3, 4, −1, 2, 1, −5, 4,其連續子數列中和最大的是 4, −1, 2, 1, 其和爲6。
-
具體求解算法
-
暴力算法
int max_sub_seq1(int *arr, int len) //初始版本 時間複雜度爲O(n^3) { int cur_num; int max_num; if (!arr || len < 0) { printf("Error input arguements\n"); return -1; } int i, j ,k; for (i = 0; i < len; ++i) { for (j = i; j < len; j++) { cur_num = 0; for (k = i; k <= j; ++k) cur_num += arr[k]; if(cur_num > max_num) { max_num = cur_num; } } } return max_num; }
-
優化後的暴力算法
int max_sub_seq2(int *arr, int len) //稍加優化 時間複雜度爲O(n^2) { int cur_num = 0; int max_num = 0; int i, j; if (!arr || len < 0) { printf("Error input arguements\n"); return -1; } for (i = 0; i < len; i++) { cur_num = 0; for (j = i; j < len; j++) { cur_num += arr[j]; if(cur_num > max_num) max_num = cur_num; } } return max_num; }
-
在線處理
/*在線處理的思想來優化代碼 時間複雜度爲n,但是對於數據元素全爲負數的序列求值爲(0)會出錯*/ int max_sub_seq3(int *arr, int len) { int i, j; int cur_num; int max_num; if (!arr || len < 0) { printf("Error input arguements\n"); return -1; } cur_num = max_num = 0; for (i = 0; i < len; i++) { cur_num += arr[i]; if(cur_num > max_num) max_num = cur_num; else if(cur_num < 0) { cur_num = 0; } } return max_num; }
備註:種方式只能用於一個數據元素非全負的數組序列,若數組序列爲全負,則其子序列求和爲)
-
分而治之
inline int max_three_num(int num1, int num2, int num3) //求得三數的最大值 { int max = 0; max = num1 > num2 ? num1:num2; max = num3 > max ? num3:max; return max; } int maxcross(int *arr, int left, int mid, int right) //求出有交叉的左右序列的和 { int i; int sum = 0; int leftSum = 0; int rightSum = 0; for (i = mid; i >=left; i--) { sum += arr[i]; if (sum > leftSum) leftSum = sum; } sum = 0; for (i = mid + 1; i <= right; i++) { sum += arr[i]; if (sum > rightSum) rightSum = sum; } return leftSum + rightSum; } int DivideandRule(int *arr, int left,int right) /* 分而治之*/ { int mid=0; int maxLeft=0, maxRight=0, maxMiddle=0; if (left == right) { if (arr[left] > 0) return arr[left]; else return 0; } mid = (left + right) / 2; maxLeft = DivideandRule(arr, left, mid); /*左序列遞歸求和*/ maxRight = DivideandRule(arr, mid + 1, right); /*右序列遞歸求和0*/ maxMiddle = maxcross(arr,left,mid,right); /* 有交集的左右序列求和 */ return max_three_num(maxLeft, maxRight, maxMiddle); }
-
運行結果