算法:栈和队列题目总结

题目1:232. 用栈实现队列
思路:用两个栈模拟队列

class MyQueue {

    Stack<Integer> stackIn;
    Stack<Integer> stackOut;

    public MyQueue() {
        stackIn=new Stack<>();
        stackOut=new Stack<>();
    }
    
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        if (stackOut.isEmpty()){
            while (!stackIn.isEmpty()){
                stackOut.push(stackIn.pop());
            }
        } 
        return stackOut.pop();
    }
    
    public int peek() {
    	//peek是获取元素,可以服用pop方法 pop完在放进去
        int pop=this.pop();
        stackOut.push(pop)
        return pop;
    }
    
    public boolean empty() {
         return stackIn.isEmpty() && stackOut.isEmpty();
    }
}

题目2:225. 用队列实现栈
思路:用两个队列模拟

class MyStack {
    //q1作为主要的队列,其元素排列顺序和出栈顺序相同
    Queue<Integer> q1 = new ArrayDeque<>();
    //q2仅作为临时放置
    Queue<Integer> q2 = new ArrayDeque<>();
    public MyStack() {}
    
    public void push(int x) {
        while(q1.size()>0){
            q2.add(q1.poll());
        }
        q1.add(x);
         while (q2.size() > 0) {
            q1.add(q2.poll());
        }
    }
    
    public int pop() {
       return q1.poll();
    }
    
    public int top() {
       return q1.peek();
    }
    
    public boolean empty() {
        return q1.empty();
    }
}

题目3:20. 有效的括号
思路:分三种情况,1.如果左边的括号多了会导致栈多出元素,2.中间括号不匹配,3.如果右边的括号多了会导致栈空。要考虑这三点,为了好处理遇到’(‘,向栈内push’)'。

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack=new Stack<>();
        char[] chars=s.toCharArray();
        for(int i=0;i<chars.length;i++){
            if(chars[i]=='('){
                stack.push(')');
            }else if(chars[i]=='{'){
                stack.push('}');
            }else if(chars[i]=='['){
                stack.push(']');
            //判断三种情况  2.中间不匹配 3.右多 栈空
            }else if(stack.isEmpty()||stack.peek()!=chars[i]){
                return false;
            }else{
                stack.pop();
            }

        }
        //1.左多 栈剩元素
        return stack.isEmpty();
    }
}

题目4:1047. 删除字符串中的所有相邻重复项
思路:用栈匹配,再反转字符串

class Solution {
    public String removeDuplicates(String s) {
        Stack<Character> stack=new Stack<>();
        char[] chars=s.toCharArray();
        for(int i=0;i<chars.length;i++){
            if(stack.isEmpty()||stack.peek()!=chars[i]){
                stack.push(chars[i]);
            }else{
                stack.pop();
            }
        }
        //反转剩余字符串
        String str = "";
        while (!stack.isEmpty()) {
            str = stack.pop() + str;
        }
        return str;
    }
}

题目5:150. 逆波兰表达式求值
思路:靠栈,如果是"+“,”-“,”*“,”/"就从栈中弹出元素,把计算好的结果再放入栈中,最后计算完栈中还有一个元素就是结果。

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<String> stack=new Stack<>();
        for(int i=0;i<tokens.length;i++){
            if(tokens[i].equals("+")){
                Integer t1=Integer.valueOf(stack.pop());
                Integer t2=Integer.valueOf(stack.pop());
                stack.push(t1+t2+"");
            }else if(tokens[i].equals("-")){    
                Integer t1=Integer.valueOf(stack.pop());
                Integer t2=Integer.valueOf(stack.pop());
                stack.push(t2-t1+"");
            }else if(tokens[i].equals("*")){    
                Integer t1=Integer.valueOf(stack.pop());
                Integer t2=Integer.valueOf(stack.pop());
                stack.push(t2*t1+"");
            }else if(tokens[i].equals("/")){    
                Integer t1=Integer.valueOf(stack.pop());
                Integer t2=Integer.valueOf(stack.pop());
                stack.push(t2/t1+"");
            }else{
                stack.push(tokens[i]);
            }
        }
        return Integer.valueOf(stack.pop());
    }
}

题目6:239. 滑动窗口最大值
思路:维护一个单调递增队列,得自己写。

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums.length == 1) {
            return nums;
        }
        int len = nums.length - k + 1;
        //存放结果元素的数组
        int[] res = new int[len];
        int num = 0;
        MyQueue myQueue = new MyQueue();
        //先将前k的元素放入队列 因为结果数组的长度与遍历长度不一样 所以前k个单独算
        for (int i = 0; i < k; i++) {
            myQueue.add(nums[i]);
        }
        res[num] = myQueue.peek();
        num++;
        for (int i = k; i < nums.length; i++) {
            //维护滑动窗口处最大值,当要移除的元素与最大值相等时,需移除最大值
            myQueue.poll(nums[i - k]);
            //滑动窗口加入最后面的元素
            myQueue.add(nums[i]);
            //记录最大值
            res[num] = myQueue.peek();
            num++;
        }
        return res;
    }
}

class MyQueue {
Deque<Integer> deque = new LinkedList<>();
    //如果要移除的元素==队列中最大值就移除,维护滑动窗口中的最大值
    void poll(int val) {
        if (!deque.isEmpty() && val == deque.peek()) {
            deque.poll();
        }
    }
    //添加元素时,如果要添加的元素大于队列尾部时,一直弹到不大于为止
    void add(int val) {
        while (!deque.isEmpty() && val > deque.getLast()) {
            deque.removeLast();
        }
        deque.add(val);
    }
    //队列队顶元素始终为最大值
    int peek() {
        return deque.peek();
    }
}

题目7:347. 前 K 个高频元素
思路:用map记录元素和出现次数,在用stream流对出现次数排序倒序排列,限制前k个

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //key为数组元素值,val为对应出现次数
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            Integer value=map.get(nums[i]);
            if(map.get(nums[i])!=null){
                value++;
                map.put(nums[i],value);
            }else{
                map.put(nums[i],1);
            }

        }
        return map.entrySet().stream()
                .sorted(Comparator.comparingInt(entry -> -entry.getValue()))
                .limit(k)
                .mapToInt(entry -> entry.getKey())
                .toArray();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值