程序员代码面试指南 —— 栈和队列(一)

注:题目来自于《程序员代码面试指南:IT名企算法与数据结构题目最优解》,该书是左程云老师的著作,值得推荐,这里仅是记录一下该书中题目的解法和个人理解

一:设计一个有getMin功能的栈
  题目:在实现栈的基本功能的基础上,再实现返回栈中的最小元素操作
  思路:可以创建一个辅助栈,辅助栈保证栈顶值既为最小值。
     当入栈的元素小于辅助栈栈顶值,则辅助栈和数据栈都进行入栈操作。
     当入栈的元素大于辅助栈栈顶值,则数据栈进行入栈操作辅助栈将栈顶元素复制一份,再将该元素进行入栈
  图解:
  在这里插入图片描述
代码:

class MyStack {
  private Stack<Integer> stackData;
  private Stack<Integer> stackMin;

  public MyStack() {
    stackData = new Stack<>();
    stackMin = new Stack<>();
  }

  public void push(int num) {
    if (stackMin.isEmpty()) {
      stackMin.push(num);
    } else if (num < getMin()) {
      stackMin.push(num);
    } else {
      int c = stackMin.peek();
      stackMin.push(c);
    }
    stackData.push(num);
  }

  public int pop() {
    if (stackData.isEmpty()) {
      throw new RuntimeException("stack is empty");
    } else {
      stackMin.pop();
      return stackData.pop();
    }
  }

  public int getMin() {
    if (stackMin.isEmpty()) {
      throw new RuntimeException("stack is empty");
    } else {
      return stackMin.peek();
    }
  }
}

测试方法:

public class GetMinStack {
  public static void main(String[] args) {
    MyStack stack = new MyStack();
    stack.push(4);
    stack.push(3);
    stack.push(4);
    stack.push(1);
    stack.push(2);
    stack.pop();
    stack.pop();
    System.out.println("min is "+stack.getMin());
  }
}

执行结果,亲测可用:

min is 3

二:由两个栈组成的队列
  题目:编写一个类,用两个栈实现队列,支持栈的基本操作(add、poll、peek)
  思路:栈是先进后出,队列是先进先出,所以刚好可以用两个栈来实现这种数据结构
     但是在数据弹出和压入到另一个栈的时候,需要注意两个点,如果stackPush要往stackPop压入数据,
     那么必须保证一次把stackPush中的数据全部压入stackPop。如果stackPop不为空,stackPush不允许向stackPop压入数据

图示:
在这里插入图片描述

代码:

class TwoStactQueue {
  public Stack<Integer> stackPush;
  public Stack<Integer> stackPop;

  public TwoStactQueue() {
    stackPop = new Stack<>();
    stackPush = new Stack<>();
  }

  public void add(int num) {
    stackPush.push(num);
  }

  public int poll() {
    if (stackPop.isEmpty() && stackPush.isEmpty()) {
      throw new RuntimeException("Queue is empty");
    } else if (stackPop.isEmpty()) {
      while (!stackPush.empty()) {
        stackPop.push(stackPush.pop());
      }
    }
    return stackPop.pop();
  }

  public int peek() {
    if (stackPop.isEmpty() && stackPush.isEmpty()) {
      throw new RuntimeException("Queue is empty");
    } else if (stackPop.isEmpty()) {
      while (!stackPush.empty()) {
        stackPop.push(stackPush.pop());
      }
    }
    return stackPop.peek();
  }
}

测试类:

public class StackToQueue {
  public static void main(String[] args) {
    TwoStactQueue queue = new TwoStactQueue();
    queue.add(1);
    queue.add(2);
    queue.add(3);
    System.out.println(queue.poll() + "," + queue.poll());
    queue.add(4);
    queue.add(5);
    System.out.println(queue.poll() + "," + queue.peek() + "," + queue.poll());
  }
}

执行结果,亲测可用:

1,2
3,4,4

三:如何仅用递归函数和栈操作逆序一个栈
  题目:将一个栈中的内容逆序输出,只用递归函数来实现
  思路:可以用两个递归函数来实现
     第一个递归函数用来将栈底数字取出,第二个递归函数用来将数字入栈
  图示:
  
在这里插入图片描述

代码:

public class ReverStack {
  public static void main(String[] args) {
    Stack<Integer> stack = new Stack<>();
    stack.push(3);
    stack.push(2);
    stack.push(1);
    reverse(stack);
    System.out.println(stack.toString());
  }

    /**
     * 将栈stack的栈底元素返回并移除
     *
     * @return 栈底元素
     */
  public static int getAndRemoveLastElement(Stack<Integer> stack){
      int result = stack.pop();
      if(stack.isEmpty()){
          return result;
      }else{
          int last = getAndRemoveLastElement(stack);
          stack.push(result);
          return last;
      }
  }

  public static void reverse(Stack<Integer> stack){
      if(stack.isEmpty()){
          return;
      }
      int i = getAndRemoveLastElement(stack);
      reverse(stack);
      stack.push(i);
  }
}

测试结果,亲测可用:

[1, 2, 3]

猜你喜欢

转载自blog.csdn.net/Kirito19970409/article/details/83656909