给定n
塔编号为1,2,3,...,n,其高度(h[i] = towers[i]
' s高度)和数字k。
两个塔 a,b 被视为朋友iff:
有多少`友谊'在那里?
解决方案很简单:
for i = 1, 2, 3, 4, 5, ..., n - k:
if h[i] == h[i+k]:
for j in range[i, i+k] :
MAX = max(MAX, h[j]
if MAX <= h[i]:
ans++
但我想以最有效的方式解决问题。请帮忙。
对于大n
,该程序将占用RAM;为了减少这一点,我使用队列来增加塔的高度而不是数组(当q.size()== k时,只需要q.pop())。使用天真解决方案检查大k的第三个条件必须花费时间。
答案 0 :(得分:0)
您可以使用deque来提供O(n)算法 每一步:
Remove too old elements from the deque head
(if currentindex - index >= k)
Remove elements from tail that have no chance to become maximum
in the k-size window (those < currentvalue)
Add new element (index) to the deque tail
这样可以在双色显示屏的头部保留最大元素的索引,这样就可以确定 - 两个塔之间的值是否更大
使用伪代码描述(滑动最小值)算法: Can min/max of moving window achieve in O(N)?
答案 1 :(得分:0)
在阐述我的评论时,您可以使用this question的答案来构建一个队列,该队列可以跟踪两个塔之间的最大元素。移至下一个元素只需O(1)
摊销时间。我在伪代码中做了一个简单的实现,假设语言支持标准堆栈(如果没有,会很惊讶)。有关说明,请参阅linked answer。
class TupleStack
Stack stack
void push(int x)
if stack.isEmpty()
stack.push((value: x, max: x))
else
stack.push((value: x, max: max(x, stack.peek().max))
int pop()
return stack.pop().value
bool isEmpty()
return stack.isEmpty()
int getMax()
if isEmpty()
return -infinity
else
return stack.peek().max
class MaxQueue
TupleStack stack1
TupleStack stack2
void enqueue(int x)
stack1.push(x)
int dequeue()
if stack2.isEmpty()
while !stack1.isEmpty()
stack2.push(stack1.pop())
return stack2.pop()
int getMax()
return max(stack1.getMax(), stack2.getMax())
您的算法现在非常简单。将第一个k
元素放入队列中。之后,重复检查距离k
的两个塔是否具有相同的高度,检查两者之间的最大值(队列的最大值)是否最多为其高度,然后移动到下两个塔。更新队列需要O(1)
摊销时间,因此该算法在O(n)
中运行,这显然是最佳的。
MaxQueue queue
for (int i = 1; i <= k; i++) // add first k towers to queue
queue.enqueue(h[i])
for (int i = k+1; i <= n; i++)
if h[i] == h[i-k] and h[i] >= queue.getMax()
ans++
queue.enqueue(h[i])
queue.dequeue()