包含 min 函數(shù)的棧


題目要求:定義棧的數(shù)據(jù)結(jié)構(gòu)饥悴,請(qǐng)?jiān)谠擃愋椭袑?shí)現(xiàn)一個(gè)能夠得到棧的最小元素的 min 函數(shù)。在該棧中瓣铣,調(diào)用 min贷揽、push、pop 的時(shí)間復(fù)雜度都是 O ( 1 ).


思路:

  1. 把每次的最小元素(之前的最小元素和新壓入data棧的元素兩者的較小值)存到輔助棧 mins 中

代碼實(shí)現(xiàn):

public class StackWithMin {

    // 數(shù)據(jù)棧
    private List<Integer> data = new ArrayList<>();

    // 輔助最小值棧
    private List<Integer> mins = new ArrayList<>();

    /**
     * 思路 1 :把每次的最小元素(之前的最小元素和新壓入data棧的元素兩者的較小值)存到輔助棧 mins 中
     *
     *  時(shí)間復(fù)雜度:O (1)
     *  空間復(fù)雜度:O (n)
     */
    private void push1(int num) throws Exception {
        data.add(num);
        if(mins.size() == 0) {
            // 初始化mins
            mins.add(num);
        } else {
            // 輔助棧mins每次push當(dāng)前data中的最小值
            int min = getMin1();
            if (num >= min) {
                mins.add(min);
            } else {
                mins.add(num);
            }
            System.out.print("push1完后mins棧中的值為:");
            for (int index : mins) {
                System.out.print(index + " ");
            }
        }
    }

    private int pop1() throws Exception {
        // 棻途龋空循捺,異常雄人,返回-1
        if(data.size() == 0) {
            throw new Exception("Stack is Empty!");
        }
        // pop時(shí)兩棧同步pop
        mins.remove(mins.size() - 1);
        System.out.print("pop1完后mins棧中的值為:");
        for (int index : mins) {
            System.out.print(index + " ");
        }
        return data.remove(data.size() - 1);
    }

    private int getMin1() throws Exception {
        // 棧空恰力,異常旗吁,返回-1
        if(mins.size() == 0) {
            throw new Exception("Stack is Empty!");
        }
        // 返回mins棧頂元素
        return mins.get(mins.size() - 1);
    }
}

測(cè)試代碼:

 @Test
    public void testStackWithMin() throws Exception {
        StackWithMin stackWithMin1 = new StackWithMin();

        /* 思路 1 */
        stackWithMin1.push1(6);
        stackWithMin1.push1(2);
        stackWithMin1.push1(2);

        System.out.println();
        int pop1 = stackWithMin1.pop1();
        System.out.print("data 棧中pop1的元素:" + pop1);
        System.out.println();
        int min1 = stackWithMin1.getMin1();
        System.out.print("data 棧中g(shù)etMin1為:" + min1);
    }

  1. 把每次的最小元素(之前的最小元素和新壓入data棧的元素兩者的較小值)的索引存到輔助棧 mins 中很钓,每次在data棧中 getMin 的時(shí)候比較其索引值與 mins 中存的索引值是否相等翻具,是則出棧回还。
public class StackWithMin {

    // 數(shù)據(jù)棧
    private List<Integer> data = new ArrayList<>();

    // 輔助最小值棧
    private List<Integer> mins = new ArrayList<>();

    /**
     * 思路 2 :把每次的最小元素(之前的最小元素和新壓入data棧的元素兩者的較小值)的索引存到輔助棧 mins 中柠硕,
     * 每次在data棧中 getMin 的時(shí)候比較其索引值與 mins 中存的索引值是否相等运提,是則出棧
     *
     * 時(shí)間復(fù)雜度:O (1)
     * 空間復(fù)雜度 :< O (n)
     */

    private void push(int num) throws Exception {
        data.add(num);
        if (mins.size() == 0) { // 初始化 mins 棧
            mins.add(0);
        } else {
            // mins 輔助棧push最小值的索引
            int minValue = getMin();
            if (num < minValue) {
                mins.add(data.size() - 1); // 將最小值在data棧中的索引 push 到 mins 棧中
            }
            System.out.print("push完后mins棧中的索引為:");
            for (int index : mins) {
                System.out.print(index + " ");
            }
        }
    }

    private int pop() throws Exception {
        // 棧為空民泵,則拋出異常
        if (data.size() == 0) {
            throw new Exception("stack is empty!");
        }

        // pop 時(shí)先獲取索引
        int popIndex = data.size() - 1;

        // 獲取 mins 輔助棧頂元素,它是最小值索引
        int minIndex = mins.get(mins.size() - 1);

        // 若 pop 出去的索引就是最小值索引胁编,mins 才出棧
        if (popIndex == minIndex) {
            mins.remove(mins.size() - 1);
        }

        System.out.print("pop后mins棧中的索引為:");
        for (int index : mins) {
            System.out.print(index + " ");
        }

        return data.remove(data.size() - 1);
    }

    /**
     *
     * @return 通過(guò) mins 棧中最小值的索引得到 data 棧中對(duì)應(yīng)的值
     * @throws Exception
     */
    private int getMin() throws Exception {
        // 棧為空鳞尔,則拋出異常
        if (data.size() == 0) {
            throw new Exception("stack is empty!");
        }

        // 獲取 mins 棧頂元素,它是最小值索引
        int minIndex = mins.get(mins.size() - 1);
        return data.get(minIndex);
    }

    @Test
    public void testStackWithMin() throws Exception {
        StackWithMin stackWithMin1 = new StackWithMin();
        
        /* 思路 2 */
        StackWithMin stackWithMin = new StackWithMin();
        stackWithMin.push(6);
        stackWithMin.push(2);
        stackWithMin.push(2);   

        System.out.println();
        int pop = stackWithMin.pop();
        System.out.print("data 棧中pop的元素:" + pop);
        System.out.println();
        int min = stackWithMin.getMin();
        System.out.print("data 棧中g(shù)etMin為:" + min);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市糕韧,隨后出現(xiàn)的幾起案子萤彩,更是在濱河造成了極大的恐慌,老刑警劉巖乒疏,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怕吴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡伟件,警方通過(guò)查閱死者的電腦和手機(jī)议经,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)咧织,“玉大人,你說(shuō)我怎么就攤上這事渠抹∩撂眩” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)圆裕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)搜锰,這世上最難降的妖魔是什么耿战? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任剂陡,我火速辦了婚禮,結(jié)果婚禮上鸭栖,老公的妹妹穿的比我還像新娘晕鹊。我一直安慰自己,他們只是感情好溅话,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布飞几。 她就那樣靜靜地躺著,像睡著了一般躁锁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上战转,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天槐秧,我揣著相機(jī)與錄音,去河邊找鬼。 笑死命雀,一個(gè)胖子當(dāng)著我的面吹牛斩箫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乘客,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼易核,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了缀匕?” 一聲冷哼從身側(cè)響起碰逸,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饵史,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后胳喷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牵辣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年纬向,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琢岩。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡师脂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出糕篇,到底是詐尸還是另有隱情酌心,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布墩崩,位于F島的核電站侯勉,受9級(jí)特大地震影響鹦筹,放射性物質(zhì)發(fā)生泄漏铐拐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一练对、第九天 我趴在偏房一處隱蔽的房頂上張望余舶。 院中可真熱鬧,春花似錦锹淌、人聲如沸匿值。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)挟憔。三九已至,卻和暖如春烟号,著一層夾襖步出監(jiān)牢的瞬間绊谭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工汪拥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留达传,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓宪赶,卻偏偏與公主長(zhǎng)得像宗弯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搂妻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容