多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > 算法學習 - 最小棧的實現O(1)時間

算法學習 - 最小棧的實現O(1)時間

來源:程序員人生   發布時間:2014-12-17 08:41:24 閱讀次數:2697次

最小棧

最小棧其實和棧沒有甚么區分的,唯1的區分在于最小棧是可以在O(1)時間內得到當前的棧空間里,最小的值是多少。

最小棧的操作

最小棧的操作和普通棧的操作沒有太大區分,唯1多了1個方法就是getMin()方法,這個方法是用來獲得當前棧內的最小值。其他方法就是Push(), Pop(), Top()...等

在O(n)時間內找到新的最小值

這里就利害了,先說普通的O(n)的方法~得到棧內最小值。是否是只要保護1個Min的變量就能夠呢?不單單是!下面舉例說明。

  • 首先:我們設置1個棧,和1個變量int Min保存最小值。
  • 然后:假定我們的操作為-Push(1),Push(2),Push(3),Push(⑴),Push(4)
  • 現在:我們來看下堆棧和Min的變化。
    stack 1 2 3 ⑴ 4 Min 1 1 1 ⑴ ⑴

我們發現Min值是在第1次插入1的時候為1,第4次插入的時候變成,這個時候我們是否是覺得很簡單,只用保護1個Min就能夠了?不是的!假定我們進行操作:Pop(),Pop()操作。我們來看看堆棧里剩下了甚么。

stack 1 2 3

那末Min呢?還是,但其實已被Pop()掉了。假設我們發現最小值被Pop()以后,我們如何更新Min呢?只能從頭遍歷,那末就需要O(n)的時間。

O(1)的辦法

這里說下如何O(1)時間內就找到,保護的變量沒有變化,但是我們在堆棧內寄存的元素需要與Min值產生關聯。
例子:
我們進行一樣的5次Push操作,壓棧順序為1 2 3 ⑴ 4

  1. 第1次棧寄存0, Min為1.
  2. 第2次棧寄存2-Min=1, Min<2 所以繼續為1.
  3. 第3次棧寄存3-Min=2, Min<3 所以繼續為1.
  4. 第4次棧寄存⑴-Min=⑵, Min>⑴ 所以Min = ⑴.
  5. 第5次棧寄存4-Min=5, Min<5 所以繼續為⑴.

大家看明白沒?我們寄存的數為x-Min.
這是Push的操作,當我們進行Pop()的時候怎樣做呢,進行兩次Pop()?

第1次棧頂元素5, 5>0, 彈出,返回 5+Min=4.
第2次棧頂元素⑵, ⑵<0,彈出,返回Min. 并更新Min=Min-(⑵).

那Top呢?

假設棧頂元素為5, 5>0 返回5+Min.
假設棧頂元素為⑵, ⑵<0 返回Min.

大家發現沒?實際上我們壓棧的時候,壓入的元素就是X-Min,那末只要壓入的元素大于Min,那末寄存的都是正數,而當X小于Min的時候,壓入的元素(X-Min)就是負數。

所以彈棧的時候:
遇到正數,直接彈出棧頂元素(X-Min)和Min的和(X-Min+Min)就能夠了。
遇到負數,說明在壓入這個元素的時候Min值有更新,那個時候的Min值被更新為新插入的X. 例如Min=1,插入⑴的時候,棧寄存⑴-Min=⑵,而Min更新為新的X值(⑴).則彈的時候就直接彈出Min就能夠了。那末我們同時也把最小值彈出了,要更新Min,更新為當前Min-(X-下1個Min)此處比較繞,多用例子理解。

代碼實現

我實現了4個版本,其中前兩個版本是O(1)級別的,后兩個是O(n)級別的。第2個版本可能有些瑕疵,假設你們看到代碼哪里毛病請評論,多謝。

1號容器實現

自己寫的結構體。

// // main.cpp // MinStack2 // // Created by Alps on 14/12/3. // Copyright (c) 2014年 chen. All rights reserved. // #include <iostream> #include <vector> using namespace std; class MinStack { public: vector<int> stack; int min; void push(int x) { if (stack.empty()) { stack.push_back(0); min = x; }else{ stack.push_back(x-min); if (x < min) { min = x; } } } void pop() { if (stack.empty()) { return; }else{ if (stack.back() < 0) { min = min - stack.back(); } stack.pop_back(); } } int top() { if (stack.empty()) { return NULL; } if (stack.back() > 0) { return stack.back()+min; }else{ return min; } } int getMin() { if (stack.empty()) { return NULL; } return min; } }; int main(int argc, const char * argv[]) { // insert code here... std::cout << "Hello, World! "; return 0; }


2號STL的stack實現

在邊沿測試的時候,我的編譯器沒出錯,但是OJ上報WA了。

// // main.cpp // MinStack4_leetcode // // Created by Alps on 14/12/3. // Copyright (c) 2014年 chen. All rights reserved. // #include <iostream> #include <stack> using namespace std; class MinStack{ public: stack<long> s; long min; void push(int x){ if (s.empty()) { s.push(0); min = x; }else{ s.push(x-min); if (x < min) { min = x; } } } void pop(){ if (s.empty()) { return; }else{ if (s.top() < 0) { min = min - s.top(); } s.pop(); } } int top(){ if (s.empty()) { return NULL; }else{ if (s.top() > 0) { return (int)(min+s.top()); }else{ return (int)min; } } } int getMin(){ if (s.empty()) { return NULL; }else{ return (int)min; } } }; int main(int argc, const char * argv[]) { int a = ⑵147483648; MinStack M; M.push(2147483646); M.push(2147483646); M.push(2147483647); printf("%d ",M.top()); M.pop(); printf("%d ",M.getMin()); M.pop(); printf("%d ",M.getMin()); M.pop(); M.push(2147483647); printf("%d ",M.top()); printf("%d ",M.getMin()); M.push(a); printf("%d ",M.top()); printf("%d ",M.getMin()); M.pop(); printf("%d ",M.getMin()); return 0; }


3號鏈表實現

自己寫的鏈表結構體。

// // main.cpp // MinStack3_leetcode // // Created by Alps on 14/12/3. // Copyright (c) 2014年 chen. All rights reserved. // #include <iostream> using namespace std; class MinStack { public: struct StackNode{ int num; StackNode *next; }; typedef StackNode* stack; stack s; MinStack(){ s = (stack)malloc(sizeof(struct StackNode)); s->next = NULL; } int min; void push(int x) { if (s->next == NULL) { stack node = (stack)malloc(sizeof(struct StackNode)); node->num = x; node->next = s->next; s->next = node; min = x; }else{ stack node = (stack)malloc(sizeof(struct StackNode)); node->num = x; node->next = s->next; s->next = node; if (x < min) { min = x; } } } void pop() { if (s->next == NULL) { return; }else{ stack temp = s->next; if (min == s->next->num && s->next->next != NULL) { s->next = s->next->next; free(temp); min = s->next->num; for (stack loop = s->next; loop != NULL; loop = loop->next) { if (min > loop->num) { min = loop->num; } } }else{ s->next = s->next->next; free(temp); } } } int top() { if (s->next == NULL) { return NULL; } return s->next->num; } int getMin() { if (s->next == NULL) { return NULL; } return min; } }; int main(int argc, const char * argv[]) { MinStack MinS; MinS.push(⑴); MinS.push(0); MinS.push(2); MinS.push(⑵); printf("%d ",MinS.top()); MinS.pop(); MinS.pop(); MinS.pop(); printf("%d ",MinS.getMin()); return 0; }


4號容器實現

最古老的版本。

// // main.cpp // MinStack_leetcode // // Created by Alps on 14/12/2. // Copyright (c) 2014年 chen. All rights reserved. // #include <iostream> #include "vector" using namespace std; class MinStack { public: struct StackNode{ int num; int min; }; vector<StackNode> stack; void push(int x) { if (stack.empty()) { StackNode S = {x,x}; stack.push_back(S); }else{ if (x < stack.back().min) { StackNode S = {x,x}; stack.push_back(S); }else{ StackNode S = {x,stack.back().min}; stack.push_back(S); } } } void pop() { if (stack.empty()) { }else{ stack.pop_back(); } } int top() { if (stack.empty()) { return NULL; } return stack.back().num; } int getMin() { if (stack.empty()) { return NULL; } return stack.back().min; } }; int main(int argc, const char * argv[]) { MinStack minstack; minstack.push(⑴); minstack.push(1); printf("%d %d ",minstack.top(), minstack.getMin()); return 0; }


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 欧美1级 | 国产精品66福利在线观看 | 免费爱爱视频 | 欧美一区二区三区大片 | 九九精品免视看国产成人 | 毛片免费网址 | 欧美日本在线播放 | 直接在线观看的三级网址 | a久久久久一级毛片护士免费 | 久久久精品久久久久久久久久久 | 欧美日韩一区视频 | 福利写真在线 | 国产永久在线观看 | 日本人护士免费xxxx视频 | 一级成人毛片 | 国产高清不卡 | 久久久xxxx | 欧美xxxx性xxxxx高清视频 | 狍和美女一级aa毛片 | 亚洲欧美日韩不卡一区二区三区 | 精品欧美激情在线看 | 欧美一级毛片免费大片 | 亚洲最大色网站 | 亚洲视频第二页 | аⅴ成人天堂中文在线 | 久久精品这里是免费国产 | 91久久精品一区二区 | 久久久久777777人人人视频 | 波多野一区二区 | 2022国产精品网站在线播放 | 欧美精品一区二区三区四区 | 最近中文字幕免费在线看 | h免费观看 | 欧美人欧美人与动人物性行为 | 久久久毛片免费全部播放 | 夜夜嗨视频 | 亚洲在线网 | 亚洲爱爱久久精品 | 欧美xxxx中国 | 欧美久久综合网 | 在线观看亚洲一区 |