Maximum subsequences and Problems

Source: Internet
Author: User

The largest subsequences and problems are one of the classic algorithm problems. Many textbooks and technical articles detail this issue. The bloggers repeat it to digest and read it later.

Problem description

Given an integer array, obtain the subsequence and maximum values of this set of numbers (for simplicity, if all the numbers in the array are negative, return 0 ). For example:

Sequence:-2 11-4 13-5-2, then the maximum subsequence is 20.

Sequence:-6 2 4-7 5 3 2-1 6-9 10-2, the maximum subsequence is 16.

Algorithm 1

1 // the exhaustive method. Add one of all the combinations to obtain the maximum value of 2 int getmaxsubsequencesum1 (INT [] array) 3 {4 int tempsum = 0, maxsum = 0, I, j, k; 5 for (I = 0; I <array. length; I ++) 6 {7 for (j = I; j <array. length; j ++) 8 {9 tempsum = 0; 10 for (k = I; k <j; k ++) // After J ++, the obtained sum of the original J numbers must be re-computed to obtain them. In algorithm 2, the repeated calculation problem is avoided. 11 tempsum + = array [k]; 12 if (tempsum> maxsum) 13 maxsum = tempsum; 14} 15} 16 return maxsum; 17}

This is an O (N3) algorithm, which is easy to understand and intuitively feels useless. For example, when I = 0, j = 3, a [0] + A [1] +... + A [3]; when I = 0, j = 4, a [0] + A [1] +... A [4]. Algorithm 2 will make an improvement. (There is a saying: do not calculate anything more than once .)

Algorithm 2


1 int getmaxsubsequencesum2 (INT [] array) 2 {3 int tempsum = 0, maxsum = 0, I, j; 4 for (I = 0; I <array. length; I ++) 5 {6 tempsum = 0; 7 for (j = I; j <array. length; j ++) 8 {9 tempsum + = array [J]; // tempsum stores the sum of the first J count and 10 if (tempsum> maxsum) 11 maxsum = tempsum; 12} 13} 14 return maxsum; 15}

A For Loop is less than the algorithm, so, and the complexity is reduced to O (n2 ). In my daily work, I am satisfied with this step, and I almost don't want to think about whether there are still (time) Better methods.

Algorithm 3


1 // divide-and-conquer) 2 int getmaxsubsequencesum3 (INT [] array, int left, int right) 3 {4 If (Left = right) // at this time, it can be determined that only one element is 5 return array [left] <0? 0: array [left]; // returns 0 6 7 int center = (left + right)/2 if it is a negative number; 8 int maxleftsum = getmaxsubsequencesum3 (array, left, center ); 9 int maxrightsum = getmaxsubsequencesum3 (array, center + 1, right); 10 11 // obtain the maximum value of the sequence ending with the last digit on the left side 12 INT maxleftbordersum = 0, leftbordersum = 0; 13 For (INT I = center; I> = left; I --) 14 {15 leftbordersum + = array [I]; 16 if (leftbordersum> maxleftbordersum) 17 maxleftbordersum = leftbordersum; 18} 19 20 // find the sequence ending with the last digit on the right. The maximum value is 21 int maxrightbordersum = 0, rightbordersum = 0; 22 for (Int J = center + 1; j <= right; j ++) 23 {24 rightbordersum + = array [J]; 25 if (rightbordersum> maxrightbordersum) 26 maxrightbordersum = rightbordersum; 27} 28 29 return math. max (math. max (maxleftsum, maxrightsum), maxleftbordersum + maxrightbordersum); 30}

The so-called divide and conquer strategy divides large problems into roughly equal subproblems, solves them and merges them into final solutions, relying on recursive algorithms. Specific to the above algorithm, the complexity is O (nlogn)(It is estimated that the coefficient n in nlogn is produced by two recursive operations of rows 8th and 9). The most confusing analysis algorithm is the appearance of logarithm. Except for the divide and conquer algorithm, we can generalize the common laws of logarithm into the following general rules: if an algorithm uses constant time (O (1 )) reduce the problem size to a part (usually 1/2), so the complexity of this algorithm is O (logn ). On the other hand, if the constant time is used to reduce the problem by a constant (for example, reduce the problem by 1), then this algorithm is O (n. Is there any better (time) algorithm?

Algorithm 4


1 int GetMaxSubsequenceSum4(int[] array) 2 { 3 int tempSum = 0, maxSum = 0; 4 for (int j = 0; j < array.Length; j++) 5 { 6 tempSum += array[j]; 7 if (tempSum > maxSum) 8 maxSum = tempSum; 9 else if (tempSum < 0)10 tempSum = 0;11 }12 return maxSum; 13 }

It is easy to understand that the time complexity of the above Code is O (n), but it is effort-consuming to figure out why the code is correct. In fact, this is an improvement of algorithm 2. During analysis, I represents the starting point of the current sequence, and J represents the end point of the current sequence. If we don't need to know the location of the best sub-sequence, I can be optimized.

One important idea is: ifA [I]If it is a negative number, it cannot represent the starting point of the sequence, because anyA [I]All subsequences starting fromA [I + 1]As a starting point for improvement. Similarly, any negative subsequence cannot be the prefix of the optimal subsequence. For example, we detectA [I]ToA [J]The subsequence of is negative, so we can push forwardI.The key conclusion is that we can not onlyIPushI + 1And we can actually keep pushing itJ + 1 (J is the first subscript that makes negative numbers from subscript I).For example, P is any subscript between I + 1 and J... + A [J] is a negative number, any subsequence starting with subscript P will not be greater than the subsequence corresponding to subscript I and contains the subsequence from a [I] to P-1. Therefore, it is safe to push I to J + 1 without missing the optimal solution.Note: althoughA [J]The sum of a sequence ending with a negative number indicates that any number in the sequence cannot beA [J]The beginning of the largest subsequence formed by the following number, but it does not indicateA [J]The previous sequence is not the largest sequence,That is to say, the maximum subsequence cannot be determined inA [J]Before or afterA [J]That is, the maximum subsequence position cannot be obtained. But make sure thatMaxsumIs the largest subsequence and.This algorithm only scans data once. Once a [J] is read and processed, it does not need to be memorized. It isOnline Algorithms.

Online algorithms: at any time, the algorithm can provide the current data solution for the data it has read.

The online algorithm of linear time in constant space is almost perfect.

Others

In addition to the sharding algorithm, the logarithm complexity mentioned in algorithm 3 has the following features: Split search (sorted set), Euclidean Algorithm (maximum common approx.), and power operation.

Time Complexity comparison (from small to large): O (1) <O (logn) <O (n) <O (nlogn) <O (n2) <O (2n) <O (N !) This can be compared at a glance with common math knowledge.

References:

Maximum subsequences and Problems

Data Structure and algorithm analysis-Chapter 2 of C language description

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.