Title:
Find the contiguous subarray within an array (containing at least one number) which have the largest sum.
for example, given the Array [?2,1,?3,4,?1,2,1,?5,4" ,
the contiguous subarray < Code style= "Font-family:menlo,monaco,consolas, ' Courier New ', monospace; font-size:13px; PADDING:2PX 4px; Color:rgb (199,37,78); Background-color:rgb (249,242,244) ">[4,?1,2,1" has the largest sum = 6 .
Click to show more practice.
More Practice:
If you had figured out the O (n) solution, try coding another solution using the divide and conquer approach, WHI CH is more subtle.
Anwser 1: kadane algorithm
idea: Add the elements of the array to the result until the sum value is less than 0, then reset the sum to 0, and always maintain an ANS variable that represents the substring and the maximum value (which will get the maximum value during the addition process).
a description of the correctness of the Kadane algorithm:for ARRAY[1...N], if ARRAY[I...J] is the most satisfying and maximal substring, then for any K (i<=k<=j), we have ARRAY[I...K] and greater than 0. Because if there is K make ARRAY[I...K] and less than 0, then we have ARRAY[K+1...J] and greater than ARRAY[I...J], which we assume the ARRAY[I...J] is the array and the maximum substring contradiction. Second, we can divide the array from left to right into several substrings, so that except for the last substring, the sum of the elements of the remaining substrings is less than 0, and for all substrings ARRAY[I...J] and any K (i<=k<j), there are array[i ... K] and greater than 0. At this point, we are going to show that the maximum substring that satisfies the condition is the prefix of one of these substrings, and it is not possible to span multiple substrings.
Attention:
1.sum add must start from a[0] and discard if a[0] is a negative value.
2. Judge sum below 0, reset 0
sum = max (sum, 0);
3. Order is important, compare a larger value first, and then see if you need to reset sum. Maintenance ans is the largest and within the array.
RET = max (ret, sum);//Only add more than 0 into the subsequence. sum = max (sum, 0);
Complexity: O (N)
AC Code:
Class Solution {public: int maxsubarray (int a[], int n) { //idea are very simple. Basically, keep adding each integer to the sequence until the sum drops below 0. If sum is negative and then should reset the sequence. int ret = a[0]; int sum = 0; for (int i = 0; i < n; i++) { //must start with a[0], if a[0] is less than 0, then go back to a[0] sum + = A[i]; RET = max (ret, sum); Only add more than 0 into the subsequence. sum = max (sum, 0); } return ret; }};
Anwser 2: Divide and conquer law
Divide and conquer method: the maximal substring and the interval has the following three kinds of conditions (Low,high respectively is the left and right boundary, Mid is (Low+high)/2):
(1) interval completely in a[low,mid-1]
(2) zone completely in a[mid+1,high]
(3) interval contains a[mid]
Follow these three conditions and keep going.
Step:
1. Locate the middle element of the array, and the maximum substring may contain or contain no intermediate elements.
2. Separate calculation
2.1 If the intermediate element is not included, continue in a[low,mid-1" and a[mid+1,high" finds the maximum and substring with the same algorithm.
< Span style= "Color:rgb (34,34,34); Font-family:arial,tahoma,helvetica,freesans,sans-serif; line-height:18px "> 2.2 if included, the maximum substring, which will contain the maximum suffix of the left string and the maximum prefix of the right string
< Span style= "Color:rgb (34,34,34); Font-family:arial,tahoma,helvetica,freesans,sans-serif; line-height:18px ">3. Returns the maximum value of three results.
< Span style= "Color:rgb (34,34,34); Font-family:arial,tahoma,helvetica,freesans,sans-serif; line-height:18px ">
< Span style= "Color:rgb (34,34,34); Font-family:arial,tahoma,helvetica,freesans,sans-serif; line-height:18px "> Attention:
< Span style= "Color:rgb (34,34,34); Font-family:arial,tahoma,helvetica,freesans,sans-serif; line-height:18px "> 1. Note How to calculate the maximum left suffix and the maximum right prefix.
< Span style= "Color:rgb (34,34,34); Font-family:arial,tahoma,helvetica,freesans,sans-serif; line-height:18px "> 2. Note The range of the left and right intervals to be solved recursively.
Calculates the left and right interval int leftans = Maxsubarray_helper (A, Ieft, middle); int Rightans = Maxsubarray_helper (A, middle+1, right);
3. Notice the recursive termination condition.
if (left = right) return a[left];
4. All elements are considered well, and some values are not dropped. Add the middle to the left interval.
Complexity: O (Nlog (n))
< Span style= "Color:rgb (34,34,34); Font-family:arial,tahoma,helvetica,freesans,sans-serif; line-height:18px "> ac Code:
< Span style= "Color:rgb (34,34,34); Font-family:arial,tahoma,helvetica,freesans,sans-serif; line-height:18px ">
Class Solution {public: int maxsubarray (int a[], int n) { if (n = = 0) return 0; Maxsubarray_helper (A, 0, n-1); } int maxsubarray_helper (int a[], int left, int. right) { if (left = right) return a[left]; int middle = left + (right-left)/2; Calculates the left and right interval int leftans = Maxsubarray_helper (A, Ieft, middle); int Rightans = Maxsubarray_helper (A, middle+1, right); Calculates the interval int leftmax = A[middle] with intermediate elements; int rightmax = a[middle+1]; int tmp = 0; for (int i = middle; I >= left; i--) { tmp + = a[i]; Leftmax = max (Leftmax, TMP); } TMP = 0; for (int i = middle+1, I <= right; i++) { tmp + = a[i]; Rightmax = max (Rightmax, TMP); } Return Max (Max (Leftans, Rightans), Leftmax + Rightmax);} };
[C + +] leetcode:58 Maximum Subarray