Returns the maximum sum of consecutive subarrays.

Source: Internet
Author: User

Sort from http://blog.csdn.net/v_JULY_v/article/details/6444021

Returns the largest sum of sub-arrays.
Description:
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 ).

For example, the input array is 1,-2, 3, 10,-4, 7, 2,-5, and the maximum sub-array is 3, 10,-4, 7, 2,
Therefore, the output is the sum of 18 of the sub-array.

 

Ideas

1. When we add a positive number, it will increase; when we add a negative number, it will decrease. If the current sum is a negative number, the sum should be discarded and re-cleared in the following tired addition. Otherwise, the negative number will decrease the sum of the following values. Implementation:

// Copyright @ July 2010/10/18 // updated, 2011.05.25. # include <iostream. h> int maxsum (int * a, int N) {int sum = 0; // it is very simple to handle all negative values, as shown, directly change this sentence to "int sum = A [0]". // You can also leave it unchanged. If all the values are negative, 0 is returned directly. Int B = 0; For (INT I = 0; I <n; I ++) {If (B <0 )//... B = A [I]; else B + = A [I]; If (sum <B) sum = B;} return sum;} int main () {int A [10] = {1,-2, 3, 10,-4, 7, 2,-5}; // int A [] = {-1, -2,-3,-4}; // test case cout where all tests are negative <maxsum (A, 8) <Endl; return 0;}/* --------------------------------- explanation: for example, if the input array is 1,-2, 3, 10,-4, 7, 2,-5, the maximum sub-array is 3, 10,-4, 7, 2, so the output is the sum of 18 of the Child array. Everything is in the following two rows: B: 0 1-1 3 13 9 16 18 13 sum: 0 1 1 3 13 13 16 18 18 actually the algorithm is very simple, the number of current values. After adding up, after B <0, assign B a value again and set it to the next element, B = A [I]. When B> sum, sum = B is updated. If B <sum, sum is kept as the original value, but not updated .. July and 10/31.

It is said that this question is the title in "programming Ball Machine", called scanning method. It is the fastest speed. The result is obtained after scanning once, And the complexity is O (n ). This algorithm is proposed by a statistician.

This algorithm is so concise and simple, and its complexity is linear. However, I think it is very difficult to come up with it, and it is not easy to prove it. Here, I am daring to write my own proof of concept:

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 addition of elements starting with 1.2 to the array in 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. :-)

 

2. Dynamic Planning: set sum [I] to the first I element, which contains the I-th element and the largest continuous sub-array. The result is the exclusive and largest sub-array. There are two options for the I + 1 element: As the first element of the new sub-array, and put it into the sub-array found above.
Sum [I + 1] = max (A [I + 1], sum [I] + A [I + 1])
Result = max (result, sum [I])
(Some of the dynamic planning ideas that a person once saw in a blog have some mistakes, but the ideas are still correct. The mistakes may be omitted. As a result, others will be defeated, this attitude is very bad)

 

3 sub-Governance: When merging, you just need to raise the limit.

// Algorithm 3: The time efficiency is O (n * log n) // the main idea of algorithm 3: Use a binary strategy to divide the sequence into two portions. // There are three possible scenarios for the longest part sequence: // [1] only appears in the left part. // [2] only appears in the right part. // [3] appears in the middle, involving both the left and right sides. // Points for discussion. Static int maxsubsum (const int A [], int left, int right) {int maxleftsum, maxrightsum; // maximum continuous subsequence values in the left and right parts. Corresponding situations [1], [2] int maxleftbordersum, maxrightbordersum; // maximum continuous subsequence values from the center to the left and right sides, corresponding to case [3 ]. Int leftbordersum, rightbordersum; int center, I; If (Left = right) base case if (a [left]> 0) return a [left]; else return 0; center = (left + right)/2; maxleftsum = maxsubsum (A, left, center); maxrightsum = maxsubsum (A, center + 1, right); maxleftbordersum = 0; leftbordersum = 0; for (I = center; I> = left; I --) {leftbordersum + = A [I]; If (leftbordersum> maxleftbordersum) maxleftbordersum = leftbordersum ;} maxrightbordersum = 0; rig Htbordersum = 0; for (I = center + 1; I <= right; I ++) {rightbordersum + = A [I]; If (rightbordersum> maxrightbordersum) maxrightbordersum = rightbordersum;} int max1 = maxleftsum> maxrightsum? Maxleftsum: maxrightsum; int max2 = maxleftbordersum + maxrightbordersum; return max1> max2? Max1: max2 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.