在 O(1) 中实现堆栈(push、pop 和 findmin)
我已经看过这个问题的两个堆栈实现,但我真的很困惑如何获得 O(1) 操作。 考虑以下示例:
S1[3542761986759]
S2[3332221111111]
这里的想法/算法是
- 在 S1 上推送元素 E
- 检查 S2 的顶部是否 >= E,如果为真,则在 S2 上插入 E
但是当调用 getMin 时,我们返回 S2 的顶部,但将 S2 留在奇怪的状态,因为 S2 包含重复的当前最小元素,因此解决方案是在 S2 中搜索下一个最小元素并返回它。这是 O(n)。
谁能帮我理解解决方案吗?
I have already seen two stack implementation of this question but I am really confused as how one could get O(1) operation.
consider following example:
S1[3542761986759]
S2[3332221111111]
The idea/algorithm here is
- Push element E on S1
- Check to see if top of S2 >= E and if true, insert E on S2
But when getMin is called, we return top of S2 but that leaves S2 in weird state as S2 contains repeated current min elements, so the solution is to search next minimum element in S2 and return it. This is O(n).
Can anyone please help me to understand the solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是不可能的。否则,您将能够在线性时间内实现比较排序:首先在 O(1) 时间内推送所有元素,总时间为 O(n),然后 n 次在 O(n) 总时间内获得最小值。
众所周知,O(n log n) 是比较排序的下限,因此具有 O(1) push 和 findmin 的解决方案不存在。
编辑:如 Gabe 所说,将“排序”替换为“比较排序”。
This is not possible. Otherwise you'd be able to implement comparison sorting in linear time: First push all elements in O(1) each, O(n) total time, and then n times get the minimum in O(n) total time.
As it is known that O(n log n) is a lower bound for comparison sorting, a solution with O(1) push and findmin can't exist.
Edit: Replaced "sorting" by "comparison sorting" as noted by Gabe.
我在这里发布完整的代码,以在堆栈中查找 min 和 mx 。
时间复杂度为 O(1)
包 com.java.util.collection.advance.datastruct;
/**
*
*@作者vsinha
*
*/
公共抽象接口堆栈{
}
包com.java.util.collection.advance.datastruct;
@SuppressWarnings(“隐藏”)
公共抽象接口 MinMaxStack 扩展了 Stack {
}
package com.java.util.collection.advance.datastruct;
导入java.util.Arrays;
/**
*
*@作者vsinha
*
* @参数
*/
公共类 MyStack 实现 Stack {
}
包 com.java.util.collection.advance.datastruct;
/**
* 在给定堆栈中查找最小值和最大值的时间复杂度为 O(1)。
*@作者vsinha
*
*/
public class MinMaxStackFinder extends MyStack Implements MinMaxStack {
}
// 测试程序
包 com.java.util.collection.advance.datastruct;
导入 java.util.Random;
public class MinMaxStackFinderApp {
}
输出:
MyStack [elements=[99, 76, 92, 49, 89, 88, 93, 33, 0, 30], size=10, top=9]
MinMaxStackFinder [minStack=MyStack [元素=[99, 76, 49, 33, 0, null, null, null, null, null], size=5, top=4]
maxStack=MyStack [元素=[99, null, null, null, null, null, null, null, null, null], size=1, top=0]]
最大:99
最小值:0
MyStack [元素=[99, 76, 92, 49, 89, null, null, null, null, null], size=5, top=4]
MinMaxStackFinder [minStack=MyStack [元素=[99, 76, 49, null, null, null, null, null, null, null], size=3, top=2]
maxStack=MyStack [元素=[99, null, null, null, null, null, null, null, null, null], size=1, top=0]]
最大:99
分钟:49
如果您有任何问题,请告诉我。
谢谢,
维卡什·辛哈
I am posting the complete code here to find min and mx in a stack.
Time complexity will be O(1)
package com.java.util.collection.advance.datastructure;
/**
*
* @author vsinha
*
*/
public abstract interface Stack {
}
package com.java.util.collection.advance.datastructure;
@SuppressWarnings("hiding")
public abstract interface MinMaxStack extends Stack {
}
package com.java.util.collection.advance.datastructure;
import java.util.Arrays;
/**
*
* @author vsinha
*
* @param
*/
public class MyStack implements Stack {
}
package com.java.util.collection.advance.datastructure;
/**
* Time complexity will be O(1) to find min and max in a given stack.
* @author vsinha
*
*/
public class MinMaxStackFinder extends MyStack implements MinMaxStack {
}
// Test program
package com.java.util.collection.advance.datastructure;
import java.util.Random;
public class MinMaxStackFinderApp {
}
Output:
MyStack [elements=[99, 76, 92, 49, 89, 88, 93, 33, 0, 30], size=10, top=9]
MinMaxStackFinder [minStack=MyStack [elements=[99, 76, 49, 33, 0, null, null, null, null, null], size=5, top=4]
maxStack=MyStack [elements=[99, null, null, null, null, null, null, null, null, null], size=1, top=0]]
MAX :99
MIN :0
MyStack [elements=[99, 76, 92, 49, 89, null, null, null, null, null], size=5, top=4]
MinMaxStackFinder [minStack=MyStack [elements=[99, 76, 49, null, null, null, null, null, null, null], size=3, top=2]
maxStack=MyStack [elements=[99, null, null, null, null, null, null, null, null, null], size=1, top=0]]
MAX :99
MIN :49
Let me know if you have any issues.
Thanks,
VIKASH SINHA
使用链表存储当前最小值。当您添加新数字时,它会查看前一个最小值,如果当前值较低,则将当前最小值更改为当前值。
例如.. 假设您有数据:3, 6, 4, 2, 7, 1。那么这就是列表的样子
value|min
这将在您推送/弹出项目时跟踪分钟。
当然,您需要有一个根节点和一个指定为“页脚”的节点,以便您可以在 O(1) 内访问末尾。
或者您可以向后移动并将内容添加到前面并在每次插入时更改根节点......这也可以。它会是这样的:
那么你就不需要“页脚”节点。
这两者都会跟踪推送值时的当前最小值。这样,当推送实际最小值时,它将知道 O(1) 中的第二个最小值是多少。
Using a linked list store the current minimum value. When you add a new number it looks at the previous min and changes the current min to the current value if the current value is lower.
E.g... Assume you have the data: 3, 6, 4, 2, 7, 1. Then this is what the list would look like
value|min
That'll keep track of the mins as you push/pop items.
Granted you'll need to have a root node and a node designated as a "footer" so you can access the end in O(1).
Or you could go backwards with it and add things to the front and change the root node every insert... that would work too. It would be something like this:
Then you wouldn't need the "footer" node.
Both of these will keep track of the current min value for when the value was pushed. That way when the actual min value is pushed, it will know what the second min value was in O(1).