解題思路
題幹要求取最小值的時間複雜度是常數級,正常取一個數組中的最小值需要O(n)的複雜度,即每個元素比較一次。
····這裏選用數組a來存儲棧····
#方法一:哈希查找
要想減小時間複雜度,最方便的方法就是空間換時間,要麼利用哈希給每個元素標號,就是維護一個序號數組大小 由最大元素值和最小元素值大小而定,即max(x)-min(x)的大小(負數的話就要用兩個哈希數組,一個表示正,一個表示負)每個元素值下內容是每個元素的排名,但是仔細想來,出棧的時候要遍歷元素範圍那麼大複雜度的數組,然後每個排名都減一,當然如果數據整體取值的範圍遠小於個數n(比如10000個數,都在0-30之間),那麼這種方法就效率很高。最後取最小值就是遍歷這兩個數組,找到下標爲1的那個索引即時所求。
#方法二:維護動態有序數組
這個方法就像STL裏的set序列一樣,每次插入元素都將其遞增排序,每次刪除元素都把該動態數組將其按插入排序刪除元素的思想向前覆蓋,這樣該數組的0號位置的元素一直都是最小值,就實現了常數級查找最小值
兩種方法的區別:
看數據的類型 ->如果數量n遠大於數的範圍就選用哈希方法 ->如果數量n遠小於數的範圍就選用維護數組的方法
-------------------- !謝謝各位大佬閱讀,感謝評論指點。代碼
class MinStack {
int MinElement[100000];
int a[100000];
int len;
public:
/** initialize your data structure here. */
MinStack() {
len = 0;
}
void push(int x) {
a[len++] = x;
if(len == 1) MinElement[0] = x;
else{
for(int i=len-2;i>=0;i--){
//從開始比較到插入需要n+1次,插入時還需要一次比較,大於x元素移動次數插入判別加1次。所以當 //所有元素都大於x時,循環已經結束,但是x還未插入、
if(MinElement[i]>=x){
MinElement[i+1] = MinElement[i];
}else{
MinElement[i+1] = x;
break;
}
if(i == 0){
MinElement[0] = x;
}
}
}
}
void pop() {
int flag=0,top = a[len-1];
for(int i=0;i<len;i++){
if(MinElement[i] == top){
flag=1;
continue;
}
if(flag){
MinElement[i-1] = MinElement[i];
}
}
len--;
}
int top() {
return a[len-1];
}
int getMin() {
return MinElement[0];
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
突然發現官方那個雙棧也不錯,有序棧維護每個元素對應的當前最小值,如果添加元素小於當前最小,那麼就再push一個當前最小元素,然後同時出棧。巧妙…