棧和隊列相關數據結構的設計問題

題目一:設計一個帶有getMin功能的棧

[leetcode155]https://leetcode.com/problems/min-stack/

解法一:兩個棧,其中help棧壓入的都是最小值,同步壓入,同步彈出,最省時間

public class MinStack {
    Stack<Integer> data;
    Stack<Integer> help;
    /** initialize your data structure here. */
    public MinStack() {
        data=new Stack<Integer>();
        help=new Stack<Integer>();
    }
    
    public void push(int x) {
        if(data.isEmpty()){
            data.push(x);
            help.push(x);
        }else{
            data.push(x);
            help.push(Math.min(help.peek(),x));
        }    
    }
    
    public void pop() {
        if(data.isEmpty())
            throw new RuntimeException("your stack is rmpty");
        data.pop();
        help.pop();
    }
    
    public int top() {
        if(data.isEmpty())
            throw new RuntimeException("your stack is rmpty");
        return data.peek();
    }
    
    public int getMin() {
        return help.peek();
    }
}

解法二:兩個棧,壓入時當前數小于等于棧頂元素才壓入,彈出時當前棧頂大于help棧頂才彈出,省了一些空間

public class MinStack {
    Stack<Integer> data;
    Stack<Integer> help;
    /** initialize your data structure here. */
    public MinStack() {
        data=new Stack<Integer>();
        help=new Stack<Integer>();
    }
    
    public void push(int x) {
        if(data.isEmpty()){
            data.push(x);
            help.push(x);
        }else{
            data.push(x);
            if(x<=help.peek())
                help.push(x);
        }    
    }
    
    public void pop() {
        // if(data.isEmpty())
        //     throw new RuntimeException("your stack is rmpty");
        int cur=data.peek();
        data.pop();
        if(cur==help.peek())
            help.pop();
    }
    
    public int top() {
        // if(data.isEmpty())
        //     throw new RuntimeException("your stack is rmpty");
        return data.peek();
        
    }
    
    public int getMin() {
        return help.peek();
    }
}

方法三:只使用一個棧,另外使用一個變量來記錄最小,棧中壓入的是與最小值的差。

public class MinStack {
    private long min;
    Stack<Long> stack;

    /** initialize your data structure here. */
    public MinStack() {
        stack=new Stack<Long>();
    }
    
    public void push(int x) {
        if(stack.isEmpty()){
            min=x;
            stack.push(0L);//為了和后面統一起來
        }
        else{
            stack.push(x-min);
            if(x<min)
                min=x;
        }
    }
    
    public void pop() {
        if(stack.isEmpty())
            return;
        long pop=stack.pop();
        if(pop<0)
            min=min-pop;
    }
    
    public int top() {
        long peek=stack.peek();
        if(peek>0)
            return (int)(min+peek);
        else
            return (int)min;
        
    }
    
    public int getMin() {
        return (int)min;
    }
}

題目二 兩個棧實現隊列

兩個棧data help,只要注意兩點
1. help為空的時候才能往里面導數。

  1. 導數就要把data中的所有數都導完。
class MyQueue {
   Stack<Integer> data=new Stack<Integer>();
   Stack<Integer> help=new Stack<Integer>();
   // Push element x to the back of queue.
   public void push(int x) {
       data.push(x);
   }

   // Removes the element from in front of queue.
   public void pop() {
       if(help.isEmpty()&&data.isEmpty())
           throw new RuntimeException("your queue is empty");
       else if(help.isEmpty()){
           while(!data.isEmpty())
               help.push(data.pop());
       }
       help.pop();
   }

   // Get the front element.
   public int peek() {
       if(help.isEmpty()&&data.isEmpty())
           throw new RuntimeException("your stack is empty");
       else if(help.isEmpty()){
           while(!data.isEmpty())
               help.push(data.pop());
       }
       return help.peek();
   }

   // Return whether the queue is empty.
   public boolean empty() {
       return help.isEmpty()&&data.isEmpty();
   }
}

題目三 兩個隊列實現棧

class MyStack {
   Queue<Integer> data=new LinkedList<Integer>();
   Queue<Integer> help=new LinkedList<Integer>();
   // Push element x onto stack.
   public void push(int x) {
       data.add(x);
   }

   // Removes the element on top of the stack.
   public void pop() {
       if(data.isEmpty())
           throw new RuntimeException("your stack is empty!");
       while(data.size()!=1){
           help.add(data.poll());
       }
       data.poll();
       while(!help.isEmpty()){
           data.add(help.poll());
       }
   }

   // Get the top element.
   public int top() {
       if(data.isEmpty())
           throw new RuntimeException("your stack is empty!");
       while(data.size()!=1){
           help.add(data.poll());
       }
       int tmp=data.peek();
       help.add(data.poll());//小心這里
       while(!help.isEmpty()){
           data.add(help.poll());
       }
       return tmp;
   }

   // Return whether the stack is empty.
   public boolean empty() {
       return data.isEmpty();
   }
}

題目四 僅使用遞歸實現棧的逆序

有利于對于遞歸的理解
要求只使用遞歸實現一個棧的逆序

思路:

假如不限條件,要實現一個棧的逆序,那么我們直接借助一個棧就可以實現了,這里不能再顯試的使用棧,那么我們就使用遞歸來利用系統的遞歸棧來實現。
這里首先思考getAndRemoveLast這個遞歸函數,用于得到一個棧的棧底元素,并且刪除設個棧底元素。然后現在我們在每次遞歸返回的時候把之前保留的元素加到棧中,就可以實現逆序。

public static void reverse(Stack<Integer> stack){
    if(stack.isEmpty())
        return;
    int i=getAndRemoveLast(stack);
    reverse(stack);
    stack.push(i);
}
public static int getAndRemoveLast(Stack<Integer> stack){
    int res=stack.pop();
    if(stack.isEmpty()){
        return res;
    }
    else{
        int last=getAndRemoveLast(stack);
        stack.push(res);
    
        return last;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,776評論 0 33
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • 課程介紹 先修課:概率統計,程序設計實習,集合論與圖論 后續課:算法分析與設計,編譯原理,操作系統,數據庫概論,人...
    ShellyWhen閱讀 2,362評論 0 3
  • 1.把二元查找樹轉變成排序的雙向鏈表 題目: 輸入一棵二元查找樹,將該二元查找樹轉換成一個排序的雙向鏈表。 要求不...
    曲終人散Li閱讀 3,371評論 0 19
  • 很討厭有一種人 滿嘴雞湯寫著些文縐縐的大道理 然后把自己經歷過的所謂的世態炎涼說得多么天花龍鳳 事實上現實卻是做事...
    Aomyl閱讀 282評論 0 0