Maximum Subarray Problem-Divide and Conquer Strategy
Reference: Introduction to Algorithms P38.
The so-called divide-and-conquer is divided into three steps:
Decomposition: The decomposition step divides the problem into a series of sub-problems, which are in the same form as the original problem, but on a smaller scale.
Solution: Solve the sub-problem recursively. If the sub-problem is small enough, stop recursion and solve it directly.
Merging: Combining the Solutions of Subproblems with the Solutions of Urban Primitive Problems
Now let's give you an integer array. Find out the element and maximum of its subarray.
First decompose the problem.
Suppose we are looking for the largest subarray of subarray A [low - > high]
We can separate this array from the middle. Get two arrays. There are three pure forms of the maximum substring required:
1. Completely located in A [low->mid].
2. Completely located in A [mid+1->high]
3. Intercepted by mid.
We can find the maximum left_sum,right_sum and cross_sum of the above three cases respectively, and then the maximum of the three cases is the answer.
For cases 1 and 2, it is obviously a sub-problem of the problem. For the third case, we take mid as the dividing point and add them to the left and right respectively. The maximum of each side is the maximum of the third case.
The c code is as follows:
#include<stdio.h> #include<stdlib.h> //There is mid in the subarray int find_max_crossing_subarray(int *A, int low, int high, int mid) { int left_sum = -0xffff; //Save the maximum sum on the left so far int sum = 0; //Save the sum of all values in A[i->mdi] for (int i = mid; i >= low; i--) { sum += A[i]; if (sum > left_sum) left_sum = sum; } int right_sum = -0xffff; //Save the largest sum on the right so far sum = 0; for (int i = mid + 1; i <= high; i++) { sum += A[i]; if (sum > right_sum) right_sum = sum; } return left_sum + right_sum; } int find_maximum_subarray(int *A, int low, int high) { if (high == low) //There is only one element in the array. return A[low]; int mid = (high + low) / 2; //Get the index of intermediate elements int left_sum = find_maximum_subarray(A, low, mid); int right_sum = find_maximum_subarray(A, mid + 1, high); int cross_sum = find_max_crossing_subarray(A, low, high, mid); //Take the maximum of three values if (left_sum >= right_sum && left_sum >= cross_sum) return left_sum; else if (right_sum >= left_sum && right_sum >= cross_sum) return right_sum; else return cross_sum; } int main() { int A[] = { 13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7 }; int sum = find_maximum_subarray(A, 0, 15); printf("%d\n", sum); }