Title: In an array, the number minus the number on the right of it gets the difference between the numbers. Find the maximum value for the difference between all numbers. For example, in the array {2, 4, 1, 16, 7, 5, 11, 9}, the maximum value for the difference is 11, which is the result of 16 minus 5.
Analysis: Seeing this topic, a lot of people's first reaction is to find the maximum and minimum value of the array, and then feel that the maximum minus the minimum is the final result. This idea ignores the important point in the topic: the difference between numbers is a number minus the number on the right. This idea doesn't work because we can't guarantee that the maximum value must be on the left side of the array.
So we can then think of letting each digit subtract all the numbers on its right, and compare the maximum number to the difference. Because each number needs to be subtracted from the O (n) digits that follow it, the total time complexity is O (N2).
Solution One: divided by the rule
Usually brute force method is not the best solution, we find ways to reduce the number of subtraction. Let's say we divide the array into two sub arrays and we don't really need to subtract the smaller numbers from the left side of the sub array to the larger numbers on the right. As we can imagine, the maximum difference between numbers is probably one of the following three scenarios: (1) both meiosis and meiosis are in the first sub array, that is, the maximum value of the difference between the number of pairs in the first child array, and (2) both the meiosis and the meiosis are in the second array, that is, the maximum value of the difference between the number pairs in the second child array. (3) is meiosis in the first child array, the maximum value of the first child array. Meiosis in the second child array is the smallest value of the second child array. The biggest of these three difference values is the maximum number of pairs in the entire array.
In the three cases mentioned earlier, it is not difficult to get the maximum value of the first child array and the smallest value of the second array, but how to get the maximum of the difference between the numbers in the two sub arrays. This is actually the problem of the original problem, we can solve it recursively. Here is the reference code for this idea:
int maxdiff_solution1 (int numbers[], unsigned length)
{
if (numbers = = NULL | | | Length < 2) return
0;
int max, min;
return Maxdiffcore (Numbers, numbers + length-1, &max, &min);
int Maxdiffcore (int* start, int* end, int* max, int* min)
{
if (end = start)
{
*max = *min = *start;
return 0x80000000;
}
int* middle = start + (End-start)/2;
int Maxleft, minleft;
int leftdiff = Maxdiffcore (Start, Middle, &maxleft, &minleft);
int maxright, minright;
int rightdiff = Maxdiffcore (middle + 1, end, &maxright, &minright);
int crossdiff = maxleft-minright;
*max = (Maxleft > Maxright)? Maxleft:maxright;
*min = (Minleft < minright)? Minleft:minright;
int maxdiff = (Leftdiff > Rightdiff)? Leftdiff:rightdiff;
MaxDiff = (MaxDiff > Crossdiff)? Maxdiff:crossdiff;
return maxdiff;
}
In function Maxdiffcore, we first get the difference between the largest number pairs in the first Leftdiff, and then the difference between the maximum number of pairs in the second sub array Rightdiff. Next, the smallest value of the second child array is subtracted from the maximum of the first Crossdiff. The maximum value of these three is the difference between the maximum number of pairs in the entire array.
Solution Two: The biggest and the problem of transforming into the solving sub-array
Next, we introduce a more ingenious solution. If you enter an array numbers of length n, we first construct a secondary array diff of length n-1, and diff[i] equals numbers[i]-numbers[i+1] (0<=i<n-1). If we add the number from the array diff to the number j (J > I), i.e. diff[i] + diff[i+1] + ... + diff[j] = (numbers[i]-numbers[i+1]) + (numbers[i + 1]- NUMBERS[I+2]) + ... + (numbers[j]–numbers[j + 1]) = Numbers[i]–numbers[j + 1].
In this analysis, we find that the difference between the largest pairs of numbers in the original array (i.e. NUMBERS[I]–NUMBERS[J + 1]) is actually the sum of the largest contiguous arrays in the auxiliary array diff. The solution to this problem has been discussed in detail in the 3rd article of the series, "finding the largest and most of the sub arrays." Based on this idea, we can write the following code:
int maxdiff_solution2 (int numbers[], unsigned length)
{
if (numbers = = NULL | | | Length < 2) return
0;
int* diff = new Int[length-1];
for (int i = 1; i < length; ++i)
diff[i-1] = numbers[i-1]-numbers[i];
int currentsum = 0;
int greatestsum = 0x80000000;
for (int i = 0; i < length-1 ++i)
{
if (currentsum <= 0)
currentsum = diff[i];
else
currentsum + = Diff[i];
if (Currentsum > Greatestsum)
greatestsum = currentsum;
}
Delete[] diff;
return greatestsum;
Solution Three: Dynamic Programming method
Since we can convert the maximum number to the maximum sum of the sub array, and the maximum of the child array can be solved by dynamic programming, then we can solve it directly through dynamic programming. Here we try to use the dynamic programming method to calculate the maximum value of the difference directly.
We define DIFF[I] as the maximum value of the difference between all numbers that are meiosis in the array. That is to say, for any H < I, Diff[i]≥number[h]-number[i]. The maximum value of diff[i] (0≤i<n) is the difference between the maximum number of pairs in the entire array.
Suppose we've got diff[i], how do we get diff[i+1? For Diff[i], there must be an H (H < i) that satisfies the difference between number[h] minus Number[i] is the largest, that is, the maximum number of all digits before number[h] should be number[i. When we ask for diff[i+1], we need to find the maximum value before the first i+1 number. The maximum value before the i+1 number can be two: the maximum value may be the maximum before the first number, and it is possible that the maximum is the first number. The maximum value before the i+1 number must be the larger of the two. We get diff[i+1] just by taking the maximum value before the i+1 number minus number[i+1].
int Maxdiff_solution3 (int numbers[], unsigned length)
{
if (numbers = = NULL | | | Length < 2) return
0;
int max = numbers[0];
int maxdiff = max-numbers[1];
for (int i = 2; i < length; ++i)
{
if (Numbers[i-1] > Max)
max = numbers[i-1];
int currentdiff = max-numbers[i];
if (Currentdiff > MaxDiff)
maxdiff = Currentdiff;
}
return maxdiff;
}
In the above code, max represents the maximum value before the first number, whereas Currentdiff represents Diff[i] (0≤i<n), diff[i] The maximum value is maxdiff in the code.
Solution Summary
The above three kinds of code, although the idea is different, but the time complexity is O (n) (the first solution of the time complexity can be expressed in a recursive formula T (n) =2 (N/2) +o (1), so the overall time complexity is O (n)). We can also note that the first method is based on recursive implementations, and recursive calls have extra time and space to consume (such as allocating space to save parameters on the call stack, temporary variables, etc.). The second method requires a secondary array of length n-1, so its space complexity is O (n). The third method has no additional time and space overhead, and its code is the simplest, so this is one of the most recommended solutions.
Bo Master He Haitao to this blog article enjoy copyright. The network reprint please indicate the source http://zhedahht.blog.163.com/. Please contact the author to organize your publication. Have any suggestion to solve the problem, welcome to inform in the comment, or add me micro bo Http://weibo.com/zhedahht or http://t.163.com/zhedahht discuss with me. Thank you.