Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
第一题:栈的最小值
一、题目描述:
请设计一个栈,除了常规栈支持的pop与push函数以外,还支持min函数,该函数返回栈元素中的最小值。执行push、pop和min操作的时间复杂度必须为O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
二、思路分析:
这题的解答我这里使用的是辅助栈。
创建两个栈,一个常规栈和一个始终保持最小值在栈顶的栈。初始化时,将Integer.MAX_VALUE放到最小栈中,这里存Integer.MAX_VALUE主要是为了减少栈为空时push操作的判断。
push方法:常规栈正常push,辅助栈压栈的值为辅助栈栈顶和当前值的最小值minStack.push(Math.min(minStack.peek(),x)),这样保证了辅助栈栈顶元素永远是所有值中的最小值。
pop方法:常规栈和辅助栈同时pop()。
top方法:返回常规栈的栈顶元素。
getMin方法:返回辅助栈的栈顶元素。
三、AC 代码:
class MinStack {
Stack<Integer> stack;
Stack<Integer> minStack;
/** initialize your data structure here. */
public MinStack() {
stack = new Stack();
minStack = new Stack();
minStack.push(Integer.MAX_VALUE);
}
public void push(int x) {
stack.push(x);
minStack.push(Math.min(minStack.peek(),x));
}
public void pop() {
stack.pop();
minStack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
第二题:化栈为队
一、题目描述:
实现一个MyQueue类,该类用两个栈来实现一个队列。
示例:
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false
说明:
- 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size 和 is empty 操作是合法的。
- 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可
- 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
二、思路分析:
两个栈实现一个队列,这个是一个比较经典的问题。
思路很简单,主要是实现pop方法。
我们知道栈是后进先出,队列是先进先出,那么使用两个栈,第一次进栈元素出栈后顺序反了,再进一次栈出栈后顺序就成了最开始的顺序。
注意点:第二个栈里面元素不为空时队列头元素就是栈顶元素,当第二个栈为空时就需要将第一个栈的所有元素放到栈2中,这样才能保证元素有序。
三、AC 代码:
class MyQueue {
Deque<Integer> stack_one;
Deque<Integer> stack_two;
/** Initialize your data structure here. */
public MyQueue() {
stack_one = new LinkedList<Integer>();
stack_two = new LinkedList<Integer>();
}
/** Push element x to the back of queue. */
public void push(int x) {
stack_one.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if(!stack_two.isEmpty()){
return stack_two.pop();
}else if(!stack_one.isEmpty()){
while(!stack_one.isEmpty()){
stack_two.push(stack_one.pop());
}
return stack_two.pop();
}else{
return -1;
}
}
/** Get the front element. */
public int peek() {
if(!stack_two.isEmpty()){
return stack_two.peek();
}else if(!stack_one.isEmpty()){
while(!stack_one.isEmpty()){
stack_two.push(stack_one.pop());
}
return stack_two.peek();
}else{
return -1;
}
}
/** Returns whether the queue is empty. */
public boolean empty() {
return stack_one.isEmpty() && stack_two.isEmpty();
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/