【Leetcode】栈篇

Queue & Deque学习

学习链接 link.

Queue

Java 集合中的 Queue 继承自 Collection 接口。
Queue是java中实现队列的接口,Queue的实现类有LinkedList和PriorityQueue。最常用的实现类是LinkedList。

Queue<Object> queue = new LinkedList();

Queue的6个方法:
在这里插入图片描述
Queue是一个先进先出的队列。

  1. 压入元素(添加):add()、offer()
    相同:未超出容量,从队尾压入元素,返回压入的那个元素。
    区别:在超出容量时,add()方法会对抛出异常,offer()返回false

  2. 弹出元素(删除):remove()、poll()
    相同:容量大于0的时候,删除并返回队头被删除的那个元素
    区别:在容量为0的时候,remove()会抛出异常,poll()返回false

  3. 获取队头元素(不删除):element()、peek()
    相同:容量大于0的时候,都返回队头元素。但是不删除。
    区别:容量为0的时候,element()会抛出异常,peek()返回null。

Deque

Deque是一个双端队列接口,继承自Queue接口,Deque的实现类是LinkedList、ArrayDeque、LinkedBlockingDeque,其中LinkedList是最常用的。

Deque有三种用途:

普通队列(一端进另一端出):
Queue queue = new LinkedList()Deque deque = new LinkedList()

双端队列(两端都可进出)
Deque deque = new LinkedList()

堆栈
Deque deque = new LinkedList()

十二种方法:
在这里插入图片描述
双端队列也可用作 LIFO(后进先出)堆栈。应优先使用此接口而不是遗留 Stack 类。在将双端队列用作堆栈时,元素被推入双端队列的开头并从双端队列开头弹出。堆栈方法完全等效于 Deque 方法,如下表所示:
在这里插入图片描述

20. 有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

在这里插入图片描述

 public boolean isValid(String s) {
 		Deque<Character> stack = new LinkedList<>();
        char[] chars = s.toCharArray();
        for (char c : chars) {
            if (c == '(') {
                stack.push(')');
            } else if (c == '[') {
                stack.push(']');
            } else if (c == '{') {
                stack.push('}');
            } else if (!stack.isEmpty() && stack.peek().equals(c)) {
                stack.pop();
            } else {
                return false;
            }
        }
        return stack.isEmpty();
    }

1047. 删除字符串中的所有相邻重复项

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
在这里插入图片描述

 public String removeDuplicates(String s) {
		Deque<Character> stack = new LinkedList<>();
        char[] chars = s.toCharArray();
        for (char c : chars) {
            if(stack.isEmpty()){
                stack.push(c);
                continue;
            }
            if(!stack.isEmpty()){
                if(stack.peek().equals(c)){
                    stack.pop();
                }else {
                    stack.push(c);
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty()){
            sb.append(stack.pollLast());
        }
        return sb.toString();
    }

150. 逆波兰表达式求值

根据 逆波兰表示法,求表达式的值。

有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
整数除法只保留整数部分。
给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
在这里插入图片描述

import java.util.Deque;
import java.util.LinkedList;
class Solution {
    public int evalRPN(String[] tokens) {
        Deque<String> stack= new LinkedList<>();    
        for (String token : tokens) {
            if(!isOp(token)){
                stack.push(token);
                continue;
            }
            if(token.equals("+")){
                String s = stack.pop();
                String s1 = stack.pop();
                int i = Integer.valueOf(s) + Integer.valueOf(s1);
                stack.push(Integer.toString(i));
                continue;
            }
            if(token.equals("-")){
                String s = stack.pop();
                String s1 = stack.pop();
                int i = Integer.valueOf(s1) - Integer.valueOf(s);
                stack.push(Integer.toString(i));
                continue;
            }
            if(token.equals("*")){
                String s = stack.pop();
                String s1 = stack.pop();
                int i = Integer.valueOf(s) * Integer.valueOf(s1);
                stack.push(Integer.toString(i));
                continue;
            }
            if(token.equals("/")){
                String s = stack.pop();
                String s1 = stack.pop();
                int i = Integer.valueOf(s1) / Integer.valueOf(s);
                stack.push(Integer.toString(i));
                continue;
            }
        }
        return Integer.valueOf(stack.pop());
    }
    public  boolean isOp(String s){
        return s.equals("+") || s.equals("-") ||s.equals("*") ||s.equals("/");
    }
}

347. 前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

在这里插入图片描述

public int[] topKFrequent(int[] nums, int k) {
		//map记录每个数字出现的频率
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            map.put(num,map.getOrDefault(num,0)+1);
        }

        Set<Map.Entry<Integer, Integer>> entries = map.entrySet();

		//new一个优先队列(内部原理与堆一样)
		//用lambda表达式设置成小顶堆的排序方式
        PriorityQueue<Map.Entry<Integer, Integer>> queue =
                new PriorityQueue<>((o1,o2)->o1.getValue()-o2.getValue());

		//加入队列中
        for (Map.Entry<Integer, Integer> entry : entries) {
            queue.offer(entry);
            //只保存我们需要的k个 其他的弹出
            if(queue.size()>k){
                queue.poll();
            }
        }

        int[] result = new int[k];
        for (int i = k - 1; i >= 0; i--) {
            result[i] = queue.poll().getKey();
        }
        return result;
        
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值