一、什么是分而治之?
分而治之方法与软件设计的模块化方法非常相似。为了解决一个大的问题,可以:
- 1) 把它分成两个或多个更小的问题;
- 2) 分别解决每个小问题;3) 把各小问题的解答组合起来,即可得到原问题的解答。
小问题通常与原问题相似,可以递归地使用分而治之策略来解决。
二、求最大子列和
对于这个问题,我们首先将数组分解:
然后求出每个序列的最大和,但是在合并的时候有三种情况:
- 最大序列和出现在左序列
- 最大序列和出现在右序列
- 最大序列和由左右序列的部分组成
对于这三种情况,进行比较,取最大
代码实现 :
#include<stdio.h> #include<limits.h> #include<math.h> int max(int a, int b) { return a > b ? a : b; } int maxsubArray(int num[], int low, int high) { if (low == high) {//分解到只有一个元素的情况 if (num[low] > INT_MIN) { return num[low]; } else { return INT_MIN; } } int mid = (low + high) / 2;//从中间元素开始分解 int maxLeft=maxsubArray(num, low, mid);//求左边的最大子序列和 int maxRight=maxsubArray(num, mid + 1, high);//求右边的最大子序列和 //最大序列和由左右序列的部分组成 int sumLeft = INT_MIN; int sumRight = INT_MIN; int a = 0, b = 0; for (int i =mid; i>=low; i--) { a += num[i]; if (a > sumLeft) { sumLeft = a; } } for (int j = mid + 1; j <= high; j++) { b += num[j]; if (b > sumRight) { sumRight = b; } } int sum = sumLeft + sumRight; return max(max(maxLeft, maxRight), sum); } int main() { int num[12] = { 1,-2,4,5,-2,8,3,-2,6,3,7,-1 }; printf("%d\n",maxsubArray( num,0, 11)); return 0; }
运行结果: