@[TOP](leetcode 栈和队列)
leetcode232 用栈实现队列(easy)
栈的顺序为后进先出,队列的顺序为先进先出。使用两个栈实现队列,一个元素需要经过两个栈才能出队列,在经过第一个栈时元素顺序被反转,经过第二个栈时再次被反转,此时就是先进先出顺序。
class MyQueue {
private Stack<Integer> in;
private Stack<Integer> out;
/** Initialize your data structure here. */
public MyQueue() {
in = new Stack<>();
out = new Stack<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
in.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if( out.isEmpty() ){
while( !in.isEmpty() ){
out.push(in.pop());
}
}
return out.pop();
}
/** Get the front element. */
public int peek() {
if(out.isEmpty()){
while( !in.isEmpty() ){
out.push(in.pop());
}
}
return out.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return in.isEmpty() && out.isEmpty();
}
}
leetcode232 用栈实现队列(easy)
在将一个元素 x 插入队列时,为了维护原来的后进先出顺序,需要让 x 插入队列首部。而队列的默认插入顺序是队列尾部,因此在将 x 插入队列尾部之后,需要让除了 x 之外的所有元素出队列,再入队列。
使用一个队列实现
class MyStack {
private Queue<Integer> queue;
/** Initialize your data structure here. */
public MyStack() {
queue = new LinkedList<>(); //注意Queue是抽象类,无法实例化对象
}
/** Push element x onto stack. */
public void push(int x) {
queue.add(x);
int count = queue.size();
while(count-- >1){
queue.add(queue.remove());
}
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue.remove();
}
/** Get the top element. */
public int top() {
return queue.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue.isEmpty();
}
}
leetcode155 最小值栈(easy)
题目:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
class MinStack {
private Stack<Integer> dataStack;
private Stack<Integer> minStack;
private int min;
/** initialize your data structure here. */
public MinStack() {
dataStack = new Stack<>();
minStack= new Stack<>();
min = Integer.MAX_VALUE;
}
public void push(int x) {
dataStack.add(x);
min = Math.min(min,x);
minStack.add(min);
}
public void pop() {
dataStack.pop();
minStack.pop();
min = minStack.isEmpty() ? Integer.MAX_VALUE : minStack.peek();
}
public int top() {
return dataStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
对于实现最小值队列问题,可以先将队列使用栈来实现,然后就将问题转换为最小值栈
用栈实现括号匹配
leetcode20 用栈实现括号匹配(easy)
Example 1: Input: “()[]{}” Output: true
Example 2: Input: “([)]” Output: false
Example 3: Input: “{[]}” Output: true
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for(char c : s.toCharArray()){
if(c == '(' || c == '[' ||c == '{'){
stack.push(c);
}else{
if(stack.isEmpty()){
return false;
}
char top = stack.pop();
boolean b1 = (top == '(' && c != ')');
boolean b2 = (top == '[' && c != ']');
boolean b3 = (top == '{' && c != '}');
if(b1 || b2 || b3){
return false;
}
}
}
return stack.isEmpty();
}
leetcode739 数组中元素与下一个比它大的元素之间的距离 (Medium)
每日温度:
Input: [73, 74, 75, 71, 69, 72, 76, 73]
Output: [1, 1, 4, 2, 1, 1, 0, 0]
在遍历数组时用栈把数组中的数存起来,如果当前遍历的数比栈顶元素的大,说明栈顶元素的下一个比它大的数就是当前元素。
单调栈:
可以维护一个存储下标的单调栈,从栈底到栈顶的下标对应的温度列表中的温度依次递减。如果一个下标在单调栈里,则表示尚未找到下一次温度更高的下标。
public int[] dailyTemperatures(int[] T) {
int length = T.length;
int[] dist = new int[length];
// Stack<Integer> indexStack = new Stack<>();
Deque<Integer> indexStack = new LinkedList<>(); //双端队列 提升速度
for(int curIndex = 0 ; curIndex<length ; curIndex++){
while(!indexStack.isEmpty() && T[curIndex]>T[indexStack.peek()]){
int preIndex = indexStack.pop();
dist[preIndex] = curIndex-preIndex;
}
indexStack.push(curIndex);
}
return dist;
}
leetcode739 循环数组中比当前元素大的下一个元素 (Medium)
输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数,输出 -1;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
单调栈
class Solution {
public int[] nextGreaterElements(int[] nums) {
int n = nums.length;
Deque<Integer> stack = new LinkedList<>();
int[] nextMax = new int[n];
Arrays.fill(nextMax,-1); //初始化nextMax数组的各个元素为-1
for(int i = 0 ; i<2*n ; i++){ //循环数组,i要经历两遍数组
int num = nums[i%n]; //当前索引指向的值
while(! stack.isEmpty() && num > nums[stack.peek()]){
nextMax[stack.pop()] = num;
}
if(i<n){
stack.push(i);
}
}
return nextMax;
}
}