Duplicate questions:
Enter an integer array, and the array contains positive and negative numbers.
One or more consecutive integers in the array form a sub-array. Each sub-array has a sum.
Returns the maximum value of the sum of all sub-arrays. The time complexity is O (n ).
This question was originally included in
Http://blog.csdn.net/v_JULY_v/article/details/6444021
OnArticleIt is also summarized, and the linear timeAlgorithmI made my own proof. Here we repeat the following:(In fact, the recursive formula below proves the correctness of the algorithm. Here we just want to try to prove it from another aspect through brute-force means, that is, to make every effort possible):
"
My idea is to prove that the scanning method contains all N ^ 2 cases, that is, all subarrays not listed can be discarded during this question scan.
1. Assume that when the algorithm scans a certain place, the sum is not greater than or equal to 0.
We can list all sub-arrays (Child arrays consisting of actually scanned elements) as three types:
1.1 starts with an element and ends with any sub-array
1.2 end with an ending element and start with any sub-array
Both the beginning and end of 1.3 are not equal to all subarrays at the beginning and end of the Current
1.1 because the traversal process has been scanned, the algorithm has been taken into consideration. 1.2 is not considered, but we can find an array in 1.2. We can see that, the sum of the number groups from the starting element to the number group in 1.2 is greater than 0 (because if it is less than 0, it indicates that the scanning process encounters a situation smaller than 0, not included in the premise 1 ), the sum must be less than the sum from the beginning to the end of the 1.2 array. In this case, you can discard
1.3 can be proved in the same way as 1.2, because we have listed all the situations at the end, so each case is the same as 1.2, so we can discard it.
2. If the current sum is less than or equal to 0, and this is the first occurrence, we can see that the sum of all the preceding values is not 0.
The intuitive conclusion is that we can discard sub-segments and sub-segments smaller than 0, but the question is, do all of his sub-segments starting with the end of this Sub-segment also need to be discarded?
The answer is yes. The sum of any sub-segments starting with this sub-segment and ending with this sub-segment is greater than 0 (the premise of Case 2). Therefore, the sum of these sub-segments is smaller than that of the current sub-segment, that is, if the value is smaller than 0, it must be discarded later. That is to say, all arrays starting with all the elements and ending with the elements ending with the current end can be discarded.
The discarded array can be analyzed recursively using two conditions: 1 and 2.
The proof of this algorithm is a bit complicated. Now I feel that it should not be wrong. At least the idea is correct. Who can help optimize the expression. :-)
"
Later, I saw the explanation of this algorithm in programming Pearl. In fact, the definition of sum less than 0 in programming pearl is as follows:
Maxendinghere = max (maxendinghere, 0)
Maxendinghere is the sum of common online algorithms. It indicates the length of the longest field ending with the current element.
We can see that this is actually a dynamic planning solution, and the optimal sub-structure can be summarized:
S [0] = max (A [0], 0)
S [I] = max (s [I-1] + A [I], 0)
That is, if the child segment ending with the previous element and less than 0 are added to the current element, the child segment ending with the current element is set to 0. In fact, this "sub-segment" is an empty segment. I don't know why it is necessary to distinguish between 0 and non-zero. In this question, the concept of "the element smaller than 0 will make the entire sub-segment value smaller" is very conspicuous, however, this case does ignore the case where all input values are negative, although the question assumes that the input values are positive and negative.
So I tried to change the structure of the optimal sub-structure and discard the concept of 0, defined:
S [0] = A [0]
S [I] = max (s [I-1] + A [I], a [I])
This looks intuitive, and the "Maximum child segment ending with element a [I]" won't be an empty child segment.
I don't know if there are any errors in this planning method. It seems that there is no problem. I implemented it:
# Include <iostream> Using Namespace STD; # Define # Max_len 100 Template < Class T> Void Maxsubarr (T * arr,Int Len, Int & Start, Int & End, T & Max_sum ){ If (LEN <= 0 ) Return ; T max_ending_sum; Int I, starts [max_len] /* The start of the Max sub array end with a [I] */ ; Max_ending_sum = Arr [ 0 ]; Max_sum = Arr [ 0 ]; Start = 0 ; End = 0 ; Starts [ 0 ] = 0 ; For (I = 1 ; I <Len; I ++ ){ // Max_ending_sum here refers to the maximum subarray length ends with element a [I-1] If (Max_ending_sum + arr [I]> Arr [I]) {max_ending_sum = Max_ending_sum + Arr [I]; starts [I] = Starts [I- 1 ];} Else {Max_ending_sum = Arr [I]; starts [I] = I ;} // Max_ending_sum now refers to the maximum subarray length ends with element a [I] If (Max_ending_sum> Max_sum) {max_sum = Max_ending_sum; Start = Starts [I]; End = I ;}}} Int Main (){ Int A [] = { 1 ,- 2 , 3 ,10 ,- 4 , 7 , 2 ,- 5 }; Int Len = 8 ; // Int A [] = {-1,-2,-3,-10,-4,-7,-2,-5 }; // Int Len = 8; Int Start, end, max_sum, I; maxsubarr (A, Len, start, end, max_sum); cout < " Maximum summary: " <Max_sum < Endl; cout < " The subarray: " ; For (I = start; I <= end; I ++ ) {Cout <A [I] < " " ;}}
Output:
Maximum summary:18The subarray:3 10-4 7 2
In particular, when the input changes:
IntA [] = {-1,-2,-3,-10,-4,-7,-2,-5};
When all values are negative, this algorithm can produce the correct result without special consideration:
Maximum Summary :-1The subarray:-1
It seems nothing wrong ~