Difficulty: Easy, Asked-in: Microsoft, Amazon, Adobe, Goldman Sachs, Walmart
Key takeaway: This is a good interview problem to learn problem-solving using binary search. The solution idea is intuitive where we modify the binary search algorithm to improve the time complexity.
You are given an array of integers that is initially increasing and then decreasing, find the maximum value in the array. Hint: keep in mind the corner cases.
Input: X[] = [18, 110, 210, 452, 810, 500, 101, 13], Output: 810
Explanation: Array is increasing from start to value 500 and then decreasing. So maximum value in the array = 810
Input: X[] = [1, 2, 3, 4, 5], Output: 5
Explanation: Array is sorted in increasing order. So maximum value in the array = 5
A simple approach is to traverse the array linearly and find the maximum.
int max_inc_dec(int A[], int low, int high)
{
int max = A[low]
for (int i = low + 1; i <= high; i = i + 1)
{
if(A[i] > max)
max = A[i]
else
break
}
return max
}
def max_inc_dec(A, low, high):
max = A[low]
for i in range(low + 1, high + 1):
if A[i] > max:
max = A[i]
else:
break
return max
The worst case occurs when the array is sorted in increasing order, and we need to traverse each element till the end. So worst-case time complexity = O(n). What would be the best and average-case time complexity? Think! We are using a constant number of variables, so space complexity = O(1)
But the critical question is: how can we improve the time complexity? How do we use the ‘first increasing and then decreasing’ property given in the input to enhance the solution's efficiency? Think!
In the ‘first increasing and then decreasing’ array, the max value in the array would be the peak point or a point after which the values started decreasing. One intuition of the efficient solution is — can we apply the idea of binary search to find such a specific point because elements in the array are sorted in a particular order? But how do we use the concept of binary search? Think! Here are the observations to modify the standard binary search algorithm:
int max_inc_dec(int A[], int low, int high)
{
if (low == high)
return A[low]
if ((high == low + 1) && A[low] >= A[high])
return A[low]
if ((high == low + 1) && A[low] < A[high])
return A[high]
int mid = low + (high - low)/2
if (A[mid] > A[mid + 1] && A[mid] > A[mid - 1])
return A[mid]
if (A[mid] > A[mid + 1] && A[mid] < A[mid - 1])
return max_inc_dec(A, low, mid-1)
else
return max_inc_dec(A, mid + 1, high)
}
def max_inc_dec(A, low, high):
if low == high:
return A[low]
if (high == low + 1) and A[low] >= A[high]:
return A[low]
if (high == low + 1) and A[low] < A[high]:
return A[high]
mid = low + (high - low) // 2
if A[mid] > A[mid + 1] and A[mid] > A[mid - 1]:
return A[mid]
if A[mid] > A[mid + 1] and A[mid] < A[mid - 1]:
return max_inc_dec(A, low, mid - 1)
else:
return max_inc_dec(A, mid + 1, high)
Since we are using recursive binary search, so the time complexity of the above program would be O(log n). The space complexity depends on the size of the call stack which is equal to the height of the recursion tree. So space complexity = O(logn). Think!
Thanks to Navtosh Kumar for his contribution in creating the first version of the content. Enjoy learning, Enjoy coding, Enjoy algorithms!