Evaluate the maximum value of the sum of the sub-arrays of the array [interview experience]

Source: Internet
Author: User

A one-dimensional array with N integer elements (A [0], A [1],..., A [N-2], A [n-1]), this array of course there are many sub-arrays, then what is the maximum value of the sum of sub-arrays?

[Solution 1]: Let's clarify the meaning of the question first.

1. The subarray of the question is continuous;

2. The question only requires summation and does not need to return the specific position of the sub-array;

3. the array element is an integer. Therefore, the array may contain positive integers, zero integers, and negative integers;

For example:

Array: [1,-2, 3, 5,-3, 2] should return: 8

Array: [0,-2, 3, 5,-1, 2] should return: 9

Array: [-9,-2,-3,-5,-3] should return:-2, which is also the sum of the largest sub-array.

These typical inputs can help us test the algorithm logic. List all possible input before writing a specific algorithm, and give the applicant the opportunity to communicate with the subject and clarify the requirements of the question. For example, what if all the values in the array are negative? Is the return value 0 or the maximum negative number? This is different from closed-book exams. You must seize the opportunity to communicate with each other.

After learning about the meaning of the question, the most direct method of our experiment is to remember Sum [I ,..., j] is the sum of the j-th element of the I-th element in array A (0 <= I <= j <n ), traverse all possible Sum [I ,... j], so the time complexity is O (N * N ):

 1 int MaxSum(int* A, int n) 2 { 3       int maxmum = -INF; 4       int sum; 5       for (int i = 0; i < n; i++) 6       { 7            for (int j = i; j < n; j++) 8            { 9                 for (int k = i; k<=j; k++)10                 {11                      sum += A[k];12                 }13                 if (sum > maxmum)14                      maxmum = sum;15            }16       }17       return maxmum;   18 }

If Sum [I ,... j] = Sum [I ,... j-1] + A [j], the last for loop in the algorithm can be omitted to avoid repeated calculation, so that the algorithm can be improved, the improved algorithm is as follows, the complexity is O (N * N ):

int MaxSum (int* A, int n){     int maxnum = -INF;     int sum;     for (int i = 0; i < n; i++)     {          sum = 0;          for (int j = i; j < n; j++)          {               sum += A[j];               if (sum > maxnum)                    maxnum = sum;          }     }     return maxnum;}

Can I continue optimization?

[Solution 2]: If the given array (A [0],..., A [n-1]) is divided into two arrays with the same length (A [0],..., A [n/2-1]) and (A [n/2],... A [n-1]), respectively find the maximum child segment and the original array (A [0],... the maximum sub-segment of A [n-1] is the maximum value in the following three cases:

1. (A [0],... the maximum sub-segment of A [n-1] and (A [0],..., the maximum sub-segments of A [n/2-1] are the same;

2. (A [0],... the maximum sub-segment of A [n-1] and (A [n/2],... the maximum sub-segment of A [n-1]) is the same;

3. The maximum child segment of (A [0],... A [n-1]) spans two elements A [n/2-1] and A [n/2];

1st and 2 are actually the same sub-Problems of halving the problem scale, which can be obtained through recursion.

As for the case in 3rd, we only need to find the sum of the largest array ending with A [n/2-1] s1 = (A [I],... A [n/2-1]) (0 <= I <n/2-1) and the sum of an array starting with A [n/2] and the largest segment s2 = (A [n/2],... A [j]) (n/2 <= j <n ). So the maximum value of 3rd cases is s1 + s2 = A [I] +... + A [n/2-1] + A [n/2] +... + A [j], you only need to traverse the original array once.

In fact, this is a divide and conquer algorithm. Each problem can be broken down into two subproblems, which are halved by a traversal algorithm. The time complexity of this Sub-rule algorithm satisfies the typical recursive formula of the sub-rule algorithm. The total time complexity is T (N) = O (N * lgN ).

[Solution 3]: The division algorithm in solution 2 has reduced the time complexity from O (N * N) to O (N * lgN), which is a good improvement, but can we further reduce the time complexity? The answer is yes. I got A prompt from the grouping algorithm: You can consider the first element of the array, A [0], and the largest array (A [I],... the relationship between A [j]) and A [0] may be as follows:

1. When 0 = I = j, element A [0] itself constitutes and is the largest segment;

2. When 0 = I <j, and the maximum segment starts with A [0;

3. When 0 <I, element A [0] has no relationship with the largest segment;

From the above three cases, we can see that a big problem (N element arrays) can be converted into a small problem (N-1 1 element arrays ). Suppose we already know (A [1],..., the sum of the largest array in A [n-1] And All [1] has been known (A [1],..., the largest array of A [1] and A [n-1] is Start [1]. Then, according to the above three situations, it is not difficult to see (A [0],..., the solution of All [0] in A [n-1]) is the maximum value of max {A [0], A [0] + Start [1] in three cases. all [1]}. Through such analysis, we can see that this problem is not post-effective and can be solved using dynamic planning.

1 int max (int x, int y) // returns x, which is greater than limit 2 {3 return (x> y) in y )? X: y; 4} 5 6 int MaxSum (int * A, int n) 7 {8 Start [n-1] = A [n-1]; 9 All [n-1] = A [n-1]; 10 for (I = n-2; I> = 0; I --) 11 {12 Start [I] = max (A [I], A [I] + Start [I + 1]); // traverse from the end of the array until the first 13 All [I] = max (Start [I], All [I + 1]); 14} 15 return All [0]; // After traversing the array, result 16 is stored in All [0}

The time complexity of the new method has been reduced to O (N.

But a new problem arises: We have applied for two additional arrays, All [] and Start []. Can we save some space?

Observe the two Recursive formulas:

1 Start[i] = max{A[i], Start[i+1] + A[i]};2 All[i] = max{Start[i], All[i+1]};

The first recursive formula: Start [I] = max {A [I], Start [I + 1] + A [I]}. If Start [I + 1] <0, Start [I] = A [I]. In addition, in the two Recursive formulas, you only need to use two variables. Start [k + 1] is only used when Start [k] is calculated, and All [k + 1] is only used when All [k] is calculated. So the program can be further improved, and only the space of O (1) is enough.

1 int max (int x, int y) 2 {3 return (x> y )? X: y; 4} 5 6 int MaxSum (int * A, int n) 7 {// check the parameter 8 nStart = A [n-1]; 9 nAll = A [n-1]; 10 for (I = n-2; I> = 0; I --) 11 {12 nStart = max (A [I], nStart + A [I]); 13 nAll = max (nStart, nAll); 14} 15 return nAll; 16}

The improved algorithm not only saves space, but also has only a few lines, but achieves high efficiency. We can also change the Syntax:

1 int MaxSum (int * A, int n) 2 {// check the parameters. 3 nStart = A [n-1]; 4 nAll = A [n-1]; 5 for (I = n-2; I> = 0; I --) 6 {7 if (nStart <0) 8 nStart = 0; // check if all is negative, how? 9 nStart + = A [I]; 10 if (nStart> nAll) 11 nAll = nStart; 12} 13 return nAll; 14}

 

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.