AfterAcademy Tech
•
23 Mar 2020

Difficulty : Easy
Asked in: Amazon
Problem Description
Given a bitonic sequence of n distinct elements, write a program to search a given element k in the bitonic sequence.
Problem Note →
Example 1
Input: nums[] = [-3, 8, 9, 20, 17, 5, 1], k = 20
Output: 3
Explanation: Element k Found at index 3
Example 2
Input: nums[] = [5, 6, 7, 8, 9, 10, 3, 2, 1], k = 30
Output: -1
In this approach, we make use of the fact that two consecutive numbers nums[i] and nums[i+1] are never equal. Thus, we can traverse over the nums array from the beginning while comparing each element with the key. If the ith element is equal to the k value, then we will return the index of the element. If the element is not found, we will simply return -1.
Psudo Code
// size is the size of the nums array
int findBitonic(int[] nums, int size, int k) {
for (i = 0 to i < size ) {
if (nums[i] == k)
return i
}
return -1
}
Complexity Analysis
Critical Ideas to Think
A more efficient way to solve this problem is by using a binary search as the input nums array is Bitonic, i.e strictly increasing and then after a certain point it is strictly decreasing, so we may find the peak element of the array by using binary search. The peak element of the bitonic array could divide the array into two parts, the first part would be increasing array and the second part would be decreasing array. Then we could easily perform binary search on any of the sub-part of the nums array depending on the peak value and the value k.
Example —

In the above figure, the peak element divides the array into two parts. Now, you can separately apply binary search on the increasing subarray and decreasing subarray and return the index of the element if found. Otherwise, just return -1.
But we first need to find the peak element using binary search →
mid from the given nums array. If this element happens to be lying in a descending sequence of numbers or a local falling slope(found by comparing nums[i] to its right neighbor), it means that the peak will always lie towards the left of this element. Thus, we reduce the search space to the left of mid(including itself) and perform the same process on the left subarray.mid lies in an ascending sequence of numbers, or a rising slope(found by comparing nums[i] to its right neighbor), it obviously implies that the peak lies towards the right of this element. Thus, we reduce the search space to the right of mid and perform the same process on the right subarray.In short,
mid element is greater than both of its adjacent elements, then mid is the peak element. Example — [1, 3, 5, 7, 6, 4, 2]mid element is greater than its next element and smaller than the previous element then maximum lies on the left side of mid. Example — [1, 7, 6, 5, 4, 3]mid element is smaller than its next element and greater than the previous element then maximum lies on the right side of mid. Example — [2, 4, 5, 6, 7, 3, 1]Solution steps
Pseudo Code
int findPeakElement(int[] nums, int low, int high) {
if (low == high)
return low
mid = (low + high) / 2
if (nums[mid] > nums[mid + 1])
return findPeakElement(nums, low, mid)
return findPeakElement(nums, mid + 1, high)
}
// Function for binary search in ascending part of array
int ascendingBinarySearch(int arr[], int low, int high, int key) {
while (low <= high) {
mid = low + (high - low) / 2
if (arr[mid] == key)
return mid
if (arr[mid] > key)
high = mid - 1
else
low = mid + 1
}
return -1
}
// Function for binary search in descending part of array
int descendingBinarySearch(int arr[], int low, int high, int key) {
while (low <= high) {
mid = low + (high - low) / 2
if (arr[mid] == key)
return mid
if (arr[mid] < key)
high = mid - 1
else
low = mid + 1
}
return -1
}
// driver function
int findBitonic(int[] nums, int size, int k) {
peak_index = findPeakElement(nums, 0, size-1)
if(k > nums[peak_index])
return -1
else if(key == nums[peak_index])
return peak_index
else {
temp = ascendingBinarySearch(nums, 0, peak_index-1, k)
if (temp != -1) {
return temp
}
// Search in right of k
temp = descendingBinarySearch(nums, peak_index+1, size-1, k)
if(temp != -1){
return temp
}
}
return -1
}
Complexity Analysis
We can reduce the space complexity from O(log n) to O(1) by using an iterative function for finding the peak element instead of a recursive function.
// Pseudo-code for finding the peak element in the bitonic array
int findPeakElement(int[] nums, low, high) {
while (low < high) {
mid = (low + high) / 2
if (nums[mid] > nums[mid + 1])
high = mid
else
low = mid + 1
}
return low
}
Critical Ideas to Think
nums[mid] with nums[mid+1] helps in finding the peak element. How?
Happy Coding! Enjoy Algorithms!!
AfterAcademy Tech
Given an array A[] of size n, you need to find the next greater element for each element in the array. Return an array that consists of the next greater element of A[i] at index i.

AfterAcademy Tech
Given an array A[] of n elements and a positive integer K, find the Kth smallest element in the array. It is given that all array elements are distinct.

AfterAcademy Tech
Given an array A[] of size n, find the most frequent element in the array, i.e. the element which occurs the most number of times.

AfterAcademy Tech
You are given an array A[] consisting of n elements. You need to find and return the number which appears more than n/2 times.
