設計一個有getMin功能的棧

Zach_z發表於2018-07-30

使用C++完成《程式設計師程式碼面試指南 IT名企演算法與資料結構題目》

題目

實現一個特殊的棧,在實現棧的基本功能基礎上,再實現返回棧中最小元素的操作

實現

使用兩個棧,一個棧用來儲存當前棧中的元素,起功能和一個正常的棧沒有區別,這個棧記為stackData;另一個棧用於儲存每一步的最小值,這個棧記為stackMin

1. 第一種方案

壓入資料規則:

假設當前資料為newNum,先將其壓入stackData,然後判斷stackMin是否為空:
- 如果為空,則newNum壓入stackMin
- 如果不為空,則比較newNum和stackMin的棧頂元素中哪一個更小
- 如果newNum更小或者兩者相等,則newNum也壓入stackMin
- 如果stackMin中棧頂元素小,則stackMin不壓入任何內容

彈出資料規則

  • 先在stackData中彈出棧頂元素,記為value。然後比較當前stackMin的棧頂元素和value哪一個更小
  • 當value等於stackMin的棧頂元素時,stackMin彈出棧頂元素
  • 當value大於stackMin的棧頂元素時,stackMin不彈出棧頂元素:返回value

getMin操作(查詢當前棧中的最小值操作)

由於stackMin始終記錄著stackData中的最小值,所以,stackMin的棧頂元素始終是當前stackData中的最小值

方案1實現程式碼

class MyStack1{
private:
    stack <int>stackData;
    stack <int>stackMin;
public:
    MyStack1(){}
    void push(int newNum){
        if(stackMin.empty()){
            stackMin.push(newNum);
        }else if (newNum <= getmin()){
            stackMin.push(newNum);
        }
        stackData.push(newNum);
    }
    int pop(){
        if(stackData.empty()){
            fprintf(stderr, "The stcack is empty\n");
            exit(0);
        }
        int value = stackData.top();
        stackData.pop();
        if(value == getmin()){
            stackMin.pop();
        }
        return value;
    }
    int getmin(){
        if(stackMin.empty()){
            fprintf(stderr,"Your Stack is empty");
            exit(0);
        }
        return stackMin.top();
    }
};

2. 第二種方案

壓入資料規則

  • 假設當前資料為newNum,先將其壓入stackData,然後判斷stackMin是否為空:
  • 如果為空,則newNum也壓入stackMin
  • 如果不為空,則比較newNum和stackMin的棧頂元素中哪一個更小:
  • 如果newNum更小或兩者相等,則newNum也壓入stackMin
  • 如果stackMin中棧頂元素小,則把stackMin的棧頂元素重複壓入stackMin

彈出資料規則

  • 在stackData中彈出資料,彈出的資料記為value;
  • 彈出stackMin中的棧頂;
  • 返回value

getMin操作(查詢當前棧中最小值操作)

由於stackMin始終記錄著stackData中的最小值,所以,stackMin的棧頂元素即為當前stackData中的最小值

方案2實現程式碼

class MyStack2{
private:
    stack <int>stackData;
    stack <int>stackMin;
public:
    MyStack2(){}
    void push(int newNum){
        if(stackMin.empty()){
            stackMin.push(newNum);
        }else if (newNum<getmin()){
            stackMin.push(newNum);
        }else{
            int newMin = stackMin.top();
            stackMin.push(newMin);
        }
        stackData.push(newNum);
    }
    int pop(){
        if(stackData.empty()){
            fprintf(stderr,"The stack is empty");
            exit(0);
        }
        stackMin.pop();
        int popNum=stackData.top();
        stackData.pop();
        return popNum;
    }
    int getmin(){
        if(stackMin.empty()){
            fprintf(stderr, "Your stack is empty");
            exit(0);
        }
        return stackMin.top();
    }
};

第一種方案在stackMin的棧頂只存放當前stackData裡的最小值一次,而第二種方案每次在壓入和彈出stackData棧時都要壓入和彈出stackMin中資料,向stackMin棧中重複壓入當前stackData裡的最小值

相關文章