• 数据结构与算法------栈和队列


     232. 用栈实现队列

    请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

    实现 MyQueue 类:

    void push(int x) 将元素 x 推到队列的末尾
    int pop() 从队列的开头移除并返回元素
    int peek() 返回队列开头的元素
    boolean empty() 如果队列为空,返回 true ;否则,返回 false

    1. 示例 1
    2. 输入:
    3. ["MyQueue", "push", "push", "peek", "pop", "empty"]
    4. [[], [1], [2], [], [], []]
    5. 输出:
    6. [null, null, null, 1, 1, false]
    7. 解释:
    8. MyQueue myQueue = new MyQueue();
    9. myQueue.push(1); // queue is: [1]
    10. myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
    11. myQueue.peek(); // return 1
    12. myQueue.pop(); // return 1, queue is [2]
    13. myQueue.empty(); // return false
    1. class MyQueue {
    2. Stack stackIn;
    3. Stack stackOut;
    4. public MyQueue() {
    5. stackIn=new Stack<>();
    6. stackOut=new Stack<>();
    7. }
    8. public void push(int x) {
    9. stackIn.push(x);
    10. }
    11. public int pop() {
    12. inToOut();
    13. return stackOut.pop();
    14. }
    15. public int peek() {
    16. inToOut();
    17. return stackOut.peek();
    18. }
    19. public boolean empty() {
    20. return stackIn.isEmpty()&&stackOut.isEmpty();
    21. }
    22. public void inToOut(){
    23. if(!stackOut.isEmpty()) return;
    24. while(!stackIn.isEmpty()){
    25. stackOut.push(stackIn.pop());
    26. }
    27. }
    28. }
    29. /**
    30. * Your MyQueue object will be instantiated and called as such:
    31. * MyQueue obj = new MyQueue();
    32. * obj.push(x);
    33. * int param_2 = obj.pop();
    34. * int param_3 = obj.peek();
    35. * boolean param_4 = obj.empty();
    36. */

    225. 用队列实现栈

    请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

    实现 MyStack 类:

    void push(int x) 将元素 x 压入栈顶。
    int pop() 移除并返回栈顶元素。
    int top() 返回栈顶元素。
    boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

    1. class MyStack {
    2. Deque queue;
    3. public MyStack() {
    4. queue=new ArrayDeque<>();
    5. }
    6. public void push(int x) {
    7. queue.addLast(x);
    8. }
    9. public int pop() {
    10. int size=queue.size();
    11. size--;
    12. while(size-->0){
    13. queue.addLast(queue.poll());
    14. }
    15. int res=queue.pollFirst();
    16. return res;
    17. }
    18. public int top() {
    19. return queue.peekLast();
    20. }
    21. public boolean empty() {
    22. return queue.isEmpty();
    23. }
    24. }

    20. 有效的括号

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

    有效字符串需满足:

    左括号必须用相同类型的右括号闭合。
    左括号必须以正确的顺序闭合。

    1. 示例 1
    2. 输入:s = "()"
    3. 输出:true
    4. 示例 2
    5. 输入:s = "()[]{}"
    6. 输出:true
    7. 示例 3
    8. 输入:s = "(]"
    9. 输出:false
    10. 示例 4
    11. 输入:s = "([)]"
    12. 输出:false
    13. 示例 5
    14. 输入:s = "{[]}"
    15. 输出:true
    1. //方法1 map
    2. class Solution {
    3. public boolean isValid(String s) {
    4. Map map=new HashMap<>();
    5. Stack stack=new Stack<>();
    6. map.put(')','(');
    7. map.put(']','[');
    8. map.put('}','{');
    9. for(char ch:s.toCharArray()){
    10. if(!map.containsKey(ch)){
    11. stack.push(ch);
    12. }else{
    13. if(stack.isEmpty()||!map.get(ch).equals(stack.peek())){
    14. return false;
    15. }else{
    16. stack.pop();
    17. }
    18. }
    19. }
    20. if(stack.isEmpty()){
    21. return true;
    22. }
    23. return false;
    24. }
    25. }
    26. //方法2
    27. class Solution {
    28. public boolean isValid(String s) {
    29. Stack stack=new Stack<>();
    30. for(char ch:s.toCharArray()){
    31. if(ch=='('){
    32. stack.push(')');
    33. }else if(ch=='['){
    34. stack.push(']');
    35. }else if(ch=='{'){
    36. stack.push('}');
    37. }else{
    38. if(!stack.isEmpty()&&ch==stack.peek()){
    39. stack.pop();
    40. }else{
    41. return false;
    42. }
    43. }
    44. }
    45. return stack.isEmpty();
    46. }
    47. }

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

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

    在 S 上反复执行重复项删除操作,直到无法继续删除。

    1. 示例:
    2. 输入:"abbaca"
    3. 输出:"ca"
    4. 解释:
    5. 例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"
    1. class Solution {
    2. public String removeDuplicates(String S) {
    3. StringBuilder sb=new StringBuilder();
    4. Stack stack=new Stack<>();
    5. for(char ch:s.charArray()){
    6. if(stack.isEmpty()||stack.peek()!=ch){
    7. stack.push(ch);
    8. }else{
    9. stack.pop();
    10. }
    11. }
    12. for(int i=stack.size();i>=0;i--){
    13. sb.append(stack.pop());
    14. }
    15. return sb.toString();
    16. }
    17. }

    150. 逆波兰表达式求值

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

    有效的算符包括 +-*/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

    1. 示例 1
    2. 输入:tokens = ["2","1","+","3","*"]
    3. 输出:9
    4. 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
    5. 示例 2
    6. 输入:tokens = ["4","13","5","/","+"]
    7. 输出:6
    8. 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
    9. 示例 3
    10. 输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
    11. 输出:22
    12. 解释:该算式转化为常见的中缀算术表达式为:
    13. ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
    14. = ((10 * (6 / (12 * -11))) + 17) + 5
    15. = ((10 * (6 / -132)) + 17) + 5
    16. = ((10 * 0) + 17) + 5
    17. = (0 + 17) + 5
    18. = 17 + 5
    19. = 22
    1. class Solution {
    2. public int evalRPN(String[] tokens) {
    3. int res=0;
    4. Deque stack=new ArrayDeque<>();
    5. for(int i=0;i
    6. if("+".equals(tokens[i])){
    7. res=stack.pop()+stack.pop();
    8. stack.push(res);
    9. }else if("-".equals(tokens[i])){
    10. res=-stack.pop()+stack.pop();
    11. stack.push(res);
    12. }else if("*".equals(tokens[i])){
    13. res=stack.pop()*stack.pop();
    14. stack.push(res);
    15. }else if("/".equals(tokens[i])){
    16. int num1=stack.pop();
    17. int num2=stack.pop();
    18. res=num2/num1;
    19. stack.push(res);
    20. }else{
    21. stack.push(Integer.valueOf(tokens[i]));
    22. }
    23. }
    24. return stack.pop();
    25. }
    26. }

    347. 前 K 个高频元素

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

    1. 示例 1:
    2. 输入: nums = [1,1,1,2,2,3], k = 2
    3. 输出: [1,2]
    4. 示例 2:
    5. 输入: nums = [1], k = 1
    6. 输出: [1]
    1. //大顶堆
    2. class Solution {
    3. public int[] topKFrequent(int[] nums, int k) {
    4. Map map=new HashMap<>();
    5. for(int num:nums){
    6. map.put(num,map.getOrDefault(num,0)+1);
    7. }
    8. PriorityQueue> queue=new PriorityQueue<>((o1,o2)->o2.getValue()-o1.getValue());
    9. for(Map.Entry entry:map.entrySet()){
    10. queue.offer(entry);
    11. }
    12. int[] res=new int[k];
    13. for(int i=k-1;i>=0;i--){
    14. res[i]=queue.poll().getKey();
    15. }
    16. return res;
    17. }
    18. }
    19. //小顶堆
    20. class Solution {
    21. public int[] topKFrequent(int[] nums, int k) {
    22. Map map=new HashMap<>();
    23. for(int num:nums){
    24. map.put(num,map.getOrDefault(num,0)+1);
    25. }
    26. PriorityQueue> queue=new PriorityQueue<>((o1,o2)->o1.getValue()-o2.getValue());
    27. for(Map.Entry entry:map.entrySet()){
    28. queue.offer(entry);
    29. if(queue.size()>k){
    30. queue.pop();
    31. }
    32. }
    33. int[] res=new int[k];
    34. for(int i=k-1;i>=0;i--){
    35. res[i]=queue.poll().getKey();
    36. }
    37. return res;
    38. }
    39. }

  • 相关阅读:
    C++性能优化笔记-6-C++元素的效率差异-7-类型转换
    【汇编】其他转移指令、call指令和ret指令
    oracle数据进程死锁查询以及解决方法
    webstorm 等idea设置鼠标滚轮+Ctrl修改字体大小
    已经2023年了,你还不会手撕轮播图?
    只分享这一次。阿里软件架构师深入底层手写JDK源码
    基金管理人公司治理和风险管理
    Java IO 面试详解
    基于蚁群算法的时延Petri网(ACOTPN)路径规划算法(Matlab代码实现)
    Java.lang.Class类 getComponentType()方法有什么功能呢?
  • 原文地址:https://blog.csdn.net/weixin_46345400/article/details/125924116