给定一个区间说A [i-j],我们可以很容易地找到使用RMQ的区间A [i-j]之间的最小值。现在我试图扭转条件,: - 给定最小值,找出包含此数字的间隔(最大长度)作为最小数量。我试图使用二进制搜索来实现它,但没有这样做。请帮我解释如何解决这个问题。谢谢 。 !!
答案 0 :(得分:1)
这是一个简单的算法,它以线性时间计算数组中每个元素左侧最接近的较小数字。我们的想法是保持一堆对(元素,位置),并在它们不再有用时弹出元素。伪代码:
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))
每个元素只被推送到堆栈一次并且最多弹出一次。这就是为什么时间复杂度为O(n)
。
它与您的问题中陈述的问题有什么关系?您可以为数组中的每个位置预先计算左侧的第一个较小元素,右侧的第一个较小元素(通过在反向数组上运行此算法)。职位i
的答案是rightSmaller[i] - leftSmaller[i] - 1
。在知道数组中每个位置的答案后,您可以轻松解决原始问题(对于给定的最小值,只需在所有i
中选择最佳答案,使array[i] = minimum
),