Given an array arr[] of integers, find out the difference between any two elements such that larger element appears after the smaller number in arr[].
Examples: If array is [2, 3, 10, 6, 4, 8, 1] then returned value should be 8 (Diff between 10 and 2). If array is [ 7, 9, 5, 6, 3, 2 ] then returned value should be 2 (Diff between 7 and 9)
Method 1 (Simple)
Use two loops. In the outer loop, pick elements one by one and in the inner loop calculate the difference of the picked element with every other element in the array and compare the difference with the maximum difference calculated so far.
#include<stdio.h>
/* The function assumes that there are at least two
elements in array.
The function returns a negative value if the array is
sorted in decreasing order.
Returns 0 if elements are equal */
int
maxDiff(
int
arr[],
int
arr_size)
{
int
max_diff = arr[1] - arr[0];
int
i, j;
for
(i = 0; i < arr_size; i++)
{
for
(j = i+1; j < arr_size; j++)
{
if
(arr[j] - arr[i] > max_diff)
max_diff = arr[j] - arr[i];
}
}
return
max_diff;
}
/* Driver program to test above function */
int
main()
{
int
arr[] = {1, 2, 90, 10, 110};
printf
(
"Maximum difference is %d"
, maxDiff(arr, 5));
getchar
();
return
0;
}
|
Time Complexity: O(n^2)
Auxiliary Space: O(1)
Method 2 (Tricky and Efficient)
In this method, instead of taking difference of the picked element with every other element, we take the difference with the minimum element found so far. So we need to keep track of 2 things:
1) Maximum difference found so far (max_diff).
2) Minimum number visited so far (min_element).
#include<stdio.h>
/* The function assumes that there are at least two
elements in array.
The function returns a negative value if the array is
sorted in decreasing order.
Returns 0 if elements are equal */
int
maxDiff(
int
arr[],
int
arr_size)
{
int
max_diff = arr[1] - arr[0];
int
min_element = arr[0];
int
i;
for
(i = 1; i < arr_size; i++)
{
if
(arr[i] - min_element > max_diff)
max_diff = arr[i] - min_element;
if
(arr[i] < min_element)
min_element = arr[i];
}
return
max_diff;
}
/* Driver program to test above function */
int
main()
{
int
arr[] = {1, 2, 6, 80, 100};
int
size =
sizeof
(arr)/
sizeof
(arr[0]);
printf
(
"Maximum difference is %d"
, maxDiff(arr, size));
getchar
();
return
0;
}
|
Time Complexity: O(n)
Auxiliary Space: O(1)
Like min element, we can also keep track of max element from right side. See below code suggested by Katamaran
int
maxDiff(
int
arr[],
int
n)
{
int
maxDiff = -1;
// Initialize Result
int
maxRight = arr[n-1];
// Initialize max element from right side
for
(
int
i = n-2; i >= 0; i--)
{
if
(arr[i] > maxRight)
maxRight = arr[i];
else
{
int
diff = maxRight - arr[i];
if
(diff > maxDiff)
{
maxDiff = diff;
}
}
}
return
maxDiff;
}
|
Method 3 (Another Tricky Solution)
First find the difference between the adjacent elements of the array and store all differences in an auxiliary array diff[] of size n-1. Now this problems turns into finding the maximum sum subarray of this difference array.
Thanks to Shubham Mittal for suggesting this solution.
#include<stdio.h>
int
maxDiff(
int
arr[],
int
n)
{
// Create a diff array of size n-1. The array will hold
// the difference of adjacent elements
int
diff[n-1];
for
(
int
i=0; i < n-1; i++)
diff[i] = arr[i+1] - arr[i];
// Now find the maximum sum subarray in diff array
int
max_diff = diff[0];
for
(
int
i=1; i<n-1; i++)
{
if
(diff[i-1] > 0)
diff[i] += diff[i-1];
if
(max_diff < diff[i])
max_diff = diff[i];
}
return
max_diff;
}
/* Driver program to test above function */
int
main()
{
int
arr[] = {80, 2, 6, 3, 100};
int
size =
sizeof
(arr)/
sizeof
(arr[0]);
printf
(
"Maximum difference is %d"
, maxDiff(arr, size));
return
0;
}
|
Output:
98
This method is also O(n) time complexity solution, but it requires O(n) extra space
Time Complexity: O(n)
Auxiliary Space: O(n)
We can modify the above method to work in O(1) extra space. Instead of creating an auxiliary array, we can calculate diff and max sum in same loop. Following is the space optimized version.
int
maxDiff (
int
arr[],
int
n)
{
// Initialize diff, current sum and max sum
int
diff = arr[1]-arr[0];
int
curr_sum = diff;
int
max_sum = curr_sum;
for
(
int
i=1; i<n-1; i++)
{
// Calculate current diff
diff = arr[i+1]-arr[i];
// Calculate current sum
if
(curr_sum > 0)
curr_sum += diff;
else
curr_sum = diff;
// Update max sum, if needed
if
(curr_sum > max_sum)
max_sum = curr_sum;
}
return
max_sum;
}
|
Time Complexity: O(n)
Auxiliary Space: O(1)
Please write comments if you find any bug in above codes/algorithms, or find other ways to solve the same problem
- very close or connected in space or time;
"contiguous events"
"immediate contact"
"the immediate vicinity"
"the immediate past"
- connecting without a break; within a common boundary;
"the 48 conterminous states"
"the contiguous 48 states"
- having a common boundary or edge; abutting; touching;
"Rhode Island has two bordering states; Massachusetts and Conncecticut"
"the side of Germany conterminous with France"
"Utah and the contiguous state of Idaho"
"neighboring cities"
用作形容词 (adj.)
本文介绍了三种高效算法来查找数组中任意两个相邻元素的最大差值,其中最后一个元素出现于前一个元素之后。算法1采用双重循环,时间复杂度为O(n^2)。算法2通过维护最小元素和最大差值,将时间复杂度降低到O(n)。算法3首先计算相邻元素之间的差值,并将其存储在一个辅助数组中,然后寻找这个差值数组中的最大和,同样达到O(n)的时间复杂度。
2240

被折叠的 条评论
为什么被折叠?



