• 【数据结构】这些栈、队列的经典面试题你还不知道吗?


    一.用队列实现栈

    力扣

    在做这道题前,我们需要有 的先驱知识,可以参考本人的这篇博客

    (41条消息) 【数据结构】栈_Living_Amethyst的博客-CSDN博客 

     

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

    实现 MyStack 类:

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

    分析:

    由于队列的特点是“先进先出”,而栈的特点是“后入先出”,所以用队列实现栈 仅用一个队列是不能实现的,需要两个队列

    我们的思路是:入的时候都入到不为空的队列里,出的时候就把不为空的队列里的除了要出的元素之外的其他(size-1)个元素都移到为空的队列里

     

     

     

    1. import java.util.LinkedList;
    2. import java.util.Queue;
    3. class MyStack {
    4. private Queue<Integer> qu1;
    5. private Queue<Integer> qu2;
    6. public MyStack() {
    7. qu1 = new LinkedList<>();
    8. qu2 = new LinkedList<>();
    9. }
    10. /**
    11. * 入到不为空的队列中
    12. * 如果都为空,就入到qu1中
    13. * @param x
    14. */
    15. public void push(int x) {
    16. if(!qu1.isEmpty()){
    17. qu1.offer(x);
    18. }else if(qu2.isEmpty()){
    19. qu2.offer(x);
    20. }else{
    21. qu1.offer(x);
    22. }
    23. }
    24. public int pop() {
    25. //1.判断当前“栈”是否为空
    26. if(empty()){
    27. return -1;
    28. }
    29. if(!qu1.isEmpty()){
    30. //从不为空的队列里出 size-1 个元素
    31. int size = qu1.size();
    32. for (int i = 0; i < size-1; i++) {
    33. /*
    34. int tmp = qu1.poll();
    35. qu2.offer(tmp);
    36. */
    37. qu2.offer(qu1.poll());
    38. }
    39. return qu1.poll();
    40. }else{
    41. //从不为空的队列里出 size-1 个元素
    42. int size = qu2.size();
    43. for (int i = 0; i < size-1; i++) {
    44. /*
    45. int tmp = qu1.poll();
    46. qu2.offer(tmp);
    47. */
    48. qu1.offer(qu2.poll());
    49. }
    50. return qu2.poll();
    51. }
    52. }
    53. public int top() {
    54. //1.判断当前“栈”是否为空
    55. if(empty()){
    56. return -1;
    57. }
    58. if(!qu1.isEmpty()){
    59. //从不为空的队列里出 size个元素
    60. int size = qu1.size();
    61. int tmp = -1;
    62. for (int i = 0; i < size; i++) {
    63. tmp = qu1.poll();
    64. qu2.offer(tmp);
    65. }
    66. return tmp;
    67. }else{
    68. //从不为空的队列里出 size个元素
    69. int size = qu2.size();
    70. int tmp = -1;
    71. for (int i = 0; i < size; i++) {
    72. tmp = qu2.poll();
    73. qu1.offer(tmp);
    74. }
    75. return tmp;
    76. }
    77. }
    78. public boolean empty() {
    79. if (qu1.isEmpty() && qu2.isEmpty()) {
    80. return true;
    81. }
    82. return false;
    83. }
    84. }

     

    二.用栈实现队列

    力扣 

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

    实现 MyQueue 类:

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

    分析:和上一题类似,若要用栈实现队列,我们需要两个栈

     

    1. import java.util.Stack;
    2. class MyQueue {
    3. private Stack<Integer> s1;
    4. private Stack<Integer> s2;
    5. public MyQueue() {
    6. s1 = new Stack<>();
    7. s2 = new Stack<>();
    8. }
    9. public void push(int x) {
    10. //入队的逻辑是把元素统一放到第一个栈中
    11. s1.push(x);
    12. }
    13. //如果第二个栈不为空,则出栈顶元素,否则把第一个栈的元素全部导入第二个栈
    14. public int pop() {
    15. if(empty()){
    16. return -1;//两个栈都是空
    17. }
    18. if (s2.empty()){
    19. //把第一个栈的元素全部导入第二个栈
    20. while(!s1.empty()){
    21. s2.push(s1.pop());
    22. }
    23. }
    24. //s2一定是不为空的
    25. return s2.pop();
    26. }
    27. public int peek() {
    28. if(empty()){
    29. return -1;//两个栈都是空
    30. }
    31. if (s2.empty()){
    32. //把第一个栈的元素全部导入第二个栈
    33. while(!s1.empty()){
    34. s2.push(s1.pop());
    35. }
    36. }
    37. //s2一定是不为空的
    38. return s2.peek();
    39. }
    40. public boolean empty() {
    41. return s1.empty() && s2.empty();
    42. }
    43. }

     

     

    三.实现一个最小栈

    力扣 

    设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

    实现 MinStack 类:

    • MinStack() 初始化堆栈对象。
    • void push(int val) 将元素val推入堆栈。
    • void pop() 删除堆栈顶部的元素。
    • int top() 获取堆栈顶部的元素。
    • int getMin() 获取堆栈中的最小元素。

    分析:

    • 定义两个栈,s1 和 minStack
    • 入栈时,s1这个栈是一定会放元素的,
    • 而对于minStack这个栈,如果minStack为空,则把元素放入minStack
    • 若不为空就把放入s1的元素与minStack的元素比较
    • 若大于minStack栈中元素,就不放入minStack栈,若小于minStack栈中元素就放入。
    • 出栈时,s1一定要出栈,同时要与minStack栈中元素比较,如果一样,那么minStack中的元素也要出栈
    1. import java.util.Stack;
    2. class MinStack {
    3. private Stack<Integer> s1;
    4. private Stack<Integer> minStack;
    5. public MinStack() {
    6. s1 = new Stack<>();
    7. minStack = new Stack<>();
    8. }
    9. public void push(int val) {
    10. s1.push(val);//s1这个栈是一定会放元素的
    11. if(minStack.empty()){
    12. minStack.push(val);
    13. }else{
    14. int x = minStack.peek();
    15. if(val <= x){ //这里必须加等号
    16. minStack.push(val);
    17. }
    18. }
    19. }
    20. public void pop() {
    21. int x = s1.pop();
    22. int x2 = minStack.peek();
    23. if(x == x2){
    24. minStack.pop();
    25. }
    26. }
    27. //获取当前栈顶元素不删除
    28. public int top() {
    29. return s1.peek();
    30. }
    31. public int getMin() {
    32. return minStack.peek();
    33. }
    34. }

     

  • 相关阅读:
    市场调研团体怎么使用无人系统生产更安全
    洛谷-官方题单版【入门篇】
    c++builder6.0 数据库查询函数select * into 功能的实现
    Linux 命令行——Shell 环境变量的查看、配置、激活
    【Python大数据笔记_day10_Hive调优及Hadoop进阶】
    贫血模型与充血模型
    从javascript到vue再到react的演变
    Linux0.11-内核中断体系
    Docker详解(上)
    【Vue插件】一款很好用的vue日历插件——vue-sweet-calendar
  • 原文地址:https://blog.csdn.net/Living_Amethyst/article/details/125399993