0
点赞
收藏
分享

微信扫一扫

【SpringBoot】SpringBoot的自动配置源码解析

非衣所思 2023-07-14 阅读 75
  • 我的思路比较蠢,用两个栈,第一个栈 A 就正常 push,等于逆序存储了队列的值,在 push 或 peek 时,把栈 A 的值 pop 并 push 到另一个栈 B,栈 B 存储的就是正确顺序的队列的值,pop 或 peek 完了之后再把 B 的 pop 回 A。
  •   class MyQueue {
          Stack<Integer> stack = new Stack<>();
          Stack<Integer> queue = new Stack<>();
      
          public MyQueue() {
      
          }
          
          public void push(int x) {
              stack.push(x);
          }
          
          public int pop() {
              while(!stack.isEmpty()){
                  queue.push(stack.pop());
              }
              int val =  queue.pop();
              while(!queue.isEmpty()){
                  stack.push(queue.pop());
              }
              return val;
          }
          
          public int peek() {
              while(!stack.isEmpty()){
                  queue.push(stack.pop());
              }
              int val = queue.peek();
              while(!queue.isEmpty()){
                  stack.push(queue.pop());
              }
              return val;
          }
          
          public boolean empty() {
              return stack.isEmpty();
          }
      }
    
  • 但是如果连续多次 pop 或 peek 时,其实我们不需要每次都把数据来回倒腾一遍,定义一个布尔值记录当前是否是顺序存储,pop 或 peek 如果不为顺序就搞成顺序,否则直接 pop 或 peek 即可,push 时如果为顺序就再倒腾回来,否则直接 push。
  •   class MyQueue {
          Stack<Integer> stack = new Stack<>();
          Stack<Integer> queue = new Stack<>();
          boolean isAsc;
      
          public MyQueue() {
      
          }
          
          public void push(int x) {
              if(isAsc){
                  isAsc = false;
                  while(!queue.isEmpty()){
                      stack.push(queue.pop());
                  }
              }
              stack.push(x);
          }
          
          public int pop() {
              if(isAsc){
                  return queue.pop();
              }
              isAsc = true;
              while(!stack.isEmpty()){
                  queue.push(stack.pop());
              }
              return  queue.pop();
          }
          
          public int peek() {
              if(isAsc){
                  return queue.peek();
              }
              isAsc = true;
              while(!stack.isEmpty()){
                  queue.push(stack.pop());
              }
              return queue.peek();
          }
          
          public boolean empty() {
              return stack.isEmpty() && queue.isEmpty();
          }
      }
    

+在上面我之所以一旦在 pop 或 peek 操作后再 push,就要把元素重新从 queue pop 回 stack,就是为了保持 stack 的倒序存储,保证了 stack 的倒序,在需要 pop 或 peek 就能重新 pop 回 queue,保证了 queue 的顺序存储。但是实际上不需要这么复杂,当遇到 pop 或 peek 操作时,只要 queue 为空就把 stack 的元素都 pop 到 queue,当 push 时就只需要正常 push 到 stack 即可,这样的话当你 pop 或 peek 时,你只有把之前顺序存储的元素用完了才会再从 stack 取元素。用完了才再填充这一件事,就是保持 stack 和 queue 按照正确顺序存储元素的关键。比如正常入队元素为 [1,2,3],stack 在 push 完 [1,2] 后为 [2,1],这时我 pop,queue 就开始填充为 [1,2],然后 pop 出 1 剩余 [2],stack 此时为 [],如果我 push 完 3 后再 pop,直接就再把 3 填充到 queue 的 [2],就成了[3,2] 然后 pop queue 的 3,实际上应该 pop 2 才对,而我把 queue 用完上一轮正确存储的元素再存储后就保证了使用 queue 的元素时,顺序都是正确的,也就是先 pop 了 1, 然后 pop 2,等到没东西 pop 了才把 stack 的 3 拿过来 pop。

  •   Stack<Integer> stack = new Stack<>();
      Stack<Integer> queue = new Stack<>();
    
      public MyQueue() {
    
      }
      
      public void push(int x) {
          stack.push(x);
      }
      
      public int pop() {
          fillQueue();
          return  queue.pop();
      }
      
      public int peek() {
          fillQueue();
          return queue.peek();
      }
      
      public boolean empty() {
          return stack.isEmpty() && queue.isEmpty();
      }
    
      public void fillQueue(){
          if(queue.isEmpty()){
              while(!stack.isEmpty()){
                  queue.push(stack.pop());
              }
          }
      }
    
举报

相关推荐

0 条评论