剑指offer 栈和队列


两个栈模拟队列

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) { 
      while(!stack1.isEmpty()){
         stack2.push(stack1.pop());
      }
        stack1.push(node);
        while(!stack2.isEmpty()){
            stack1.push(stack2.pop());
        }
        
    }
    
    public int pop() {
        if(!stack1.isEmpty()){
            return stack1.pop();
        }else
            return -1;
       
    }  
    
}
import java.util.Stack;

public class Solution {
    //思路 stack1完全做输入栈 pop时stack做输出栈
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        
        stack1.push(node);
       
    }
    
    public int pop() {
         if(stack2.isEmpty()){
             while(!stack1.isEmpty()){
                 stack2.push(stack1.pop());        
             }
         }
    return stack2.pop();
    }
}

用两个队列实现栈

public class TwoQueue {

    Queue<Integer> a = new LinkedList<Integer>();
    Queue<Integer> b = new LinkedList<Integer>();


    //a入栈
    public void push(int node) {
        a.offer(node);
        while(!b.isEmpty()){
            b.offer(a.poll());
        }
        Queue temp=a;
        a=b;
        b=a;
    }



    public int pop() {
         return b.poll();
    }
}

包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
答案
这道题也很简单,主要是实现min函数查找栈中的最小元素,且时间复杂度为1。对空间没有要求,所以可以借助额外空间。
思路:
定义两个栈,dataStack和minStack,dataStack用来保存数据,minStack用来存放最小数。
每次使用push函数存放数据的时候,首先将数据放在dataStack中,然后再判断minStack栈顶元素是否小于或者等于当前要存放的数据,如果不是,则将数据存放minStack,如果是,则将minStack的栈顶元素再次存放道minStack中,确保dataStack和minStack的相同高度。

//两个栈
 class MinStack {

    Stack<Integer> stack;
    Stack<Integer> minS;

    /** initialize your data structure here. */
    public MinStack() {
    minS=new Stack<Integer>();
      stack=new Stack<Integer>(); 
    }
    
    public void push(int x) {
          stack.push(x);
    if(minS.isEmpty()||minS.peek()>=x){
         minS.push(x);
      }      
    }
    
    public void pop() { 
        // int x = stack.pop();
        // if(x == minS.peek()){
        //      minS.pop();
        //  }

         //注意这里不能用==,====比较的是Integer对象
    if(stack.peek().equals(minS.peek())){
        minS.pop();
    }
      stack.pop();
    }
    
    public int top() {
      return   stack.peek();
    }
    
    public int getMin() {
      return    minS.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();
 */

栈的压入、弹出序列

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
答案
思路:
借用一个辅助栈,将压入序列逐一压入栈,每压入一个元素,都用栈顶元素与弹出序列从头比较,如果不相等则继续压入,如果相等,删除栈顶元素,弹出序列向后移动一位,再继续比较……
当整个程序结束,如果栈中还有元素,则该弹出序列不是这个栈的弹出序列,反之则是。

import java.util.*;

public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
          Stack<Integer> stack=new Stack<>();
        
         for(int i=0,j=0;i<pushA.length;i++){
             stack.push(pushA[i]);
             while(!stack.isEmpty()&&stack.peek()==popA[j]){
                 stack.pop(); 
                 j++;
             }
        }   
      return stack.isEmpty();
    }
}

单调队列

剑指 Offer 59 - I. 滑动窗口的最大值

在这里插入图片描述

```java
  public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums== null||nums.length==0) { 
			return new int[0];
		}
        if( k < 1 ||nums.length < k) return null; 
		LinkedList<Integer> qmax = new LinkedList<Integer>();
		int[] res = new int[nums.length - k + 1];
		int index = 0;
		for (int i = 0; i < nums.length; i++) {
			while (!qmax.isEmpty() && nums[qmax.peekLast()] <= nums[i]) {
				qmax.pollLast();
			}
			qmax.addLast(i);
                   //如果滑动窗口长度大于k,就删除队首元素
			if (qmax.peekFirst() == i - k) {
				qmax.pollFirst();
			}

                    //从第三个数i=2开始计数
			if (i >= k - 1) {
				res[index++] = nums[qmax.peekFirst()];
			}
		}
		return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值