-1

Given an Interval say A[i-j], We can easily find out the minimum value in between the Interval A[i-j] using RMQ. Now I'm trying to reverse the Condition,:- Given a minimum, find out the interval(max length) which contains this number as a minimum number. I was trying to implement this using Binary Search but failed to do so. Please help me to explain How to approach this problem. Thank You . !!

monsterspy
  • 43
  • 5
  • 2
    Not going to just write the code for you, but the way I would approach that problem would be 1) find the target value in the array, and then 2) extend your interval to the left in the array while the values are greater than the target and 3) do the same to the right... Binary search is not the right tool for this, because it requires that the array be sorted in order to work (in which case finding the interval is trivial) and, when given an unsorted array, there are no guarantees about the values in between two points... – twalberg Dec 26 '14 at 18:51
  • "extend your interval to the left in the array". let the array is {5,4,3,2,1}. and minimum value is 1. How to efficiently traverse to the left instead of extending the Interval by 1 in that case . – monsterspy Dec 26 '14 at 19:02

1 Answers1

1

Here is a simple algorithm that computes the closest smaller number to the left from each element of the array in linear time. The idea is to maintain a stack of pairs (element, position) and pop off the elements when they are not useful anymore. Pseudo code:

stack = new Stack<Pair>() // an empty stack of pairs(element, position)
leftSmaller = new int[n] // an array to store the answer
fill(leftSmaller, -1) 
for (i = 0; i < n; i++) // n is the size of the given array
    while (!stack.isEmpty() and stack.top().first >= array[i]) // pop the elements from the stack while they are larger the current element
        stack.pop()
    if (!stack.isEmpty()) // if there is a smaller element 
        leftSmaller[i] = stack.top().second // its position is the answer for the current position
    stack.push(new Pair(array[i], i))

Each element is pushed to the stack only once and popped at most once. That's why the time complexity is O(n).

How is it related to the problem stated in your question? You can precompute the first smaller element to the left for each position in the array, the first smaller element to the right(by running this algorithm on a reversed array). The answer for the position i is rightSmaller[i] - leftSmaller[i] - 1. After knowing the answer for each position in the array, you can easily solve the original problem(for a given minimum, just pick the best answer among all i such that array[i] = minimum),

kraskevich
  • 18,368
  • 4
  • 33
  • 45