1.用兩個棧實現
入棧:乙個棧作為資料棧,乙個棧作為最小值棧,往資料棧中直接壓入資料,比較此時資料棧棧頂元素和min棧棧頂元素的大小,若min棧的棧頂元素小,則往min棧中壓入棧頂元素,若要資料棧棧頂元素小,則壓入資料棧棧頂元素。
出棧:資料棧和min棧同時pop
取最小值:取min棧的棧頂元素
//用兩個棧實現
template
class stack1
void pop()
else
return;
}t& min()
private:
stack
sdata; //資料棧
stack
smin; //最小值棧
};
2.用乙個棧實現
入棧:min值的確定方法和兩個棧時一樣,不過資料和min值壓入同乙個棧,資料先壓入,min值後壓入。
出棧:pop兩次。
取最小值:取棧頂元素值。
//用乙個棧實現
template
class stack2
else
}void pop()
else
return;
}t& min()
private:
stack
s;};
push和pop都只進行了常數次,所以時間複雜度為o(1)
1.保證在整個過程中,乙個棧為空,則另外乙個棧要麼為空,要麼有資料,不能出現兩個棧同時有資料的情況,這樣就可以借助為空的那個棧進行push和pop等操作了。
template
t>
class
queue1
else
if (!s1.empty() && s2.empty())
else
}void pop()
s2.pop(); //真正要刪除的那個數
while (!s2.empty()) //把剩下的數放回s1中
}else
if (s1.empty() && !s2.empty())
s1.pop(); //真正要刪除的那個數
while (!s1.empty()) //把剩下的數放回s2中
}else
return;
}t& front()
t top = s2.top(); //儲存隊頭
while (!s2.empty()) //把所有的數放回s1中
return top;
}else
if (s1.empty() && !s2.empty())
t top = s1.top(); //儲存隊頭
while (!s1.empty()) //把所有的數放回s2中
return top;}}
t& back()
else
if (s1.empty() && !s2.empty())
}bool empty()
size_t size()
private:
stacks1;
stacks2;
};
2.確保其中乙個棧只能push,另乙個棧只能pop
template
class queue2
void pop()
sout.pop(); //佇列真正要刪除的數
}else
}t& front()
return sout.top(); //儲存隊頭
}else
}t& back()
else
return sin.top();}}
bool empty()
size_t size()
private:
stack
sin; //sin中只push
stack
sout; //sout中只pop
};
template
class stack
else
if (!q1.empty() && q2.empty())
else
}void pop()
q1.pop(); //棧真正要刪除的數
}else
if (q1.empty() && !q2.empty())
q2.pop(); //棧真正要刪除的數
}else
return;
}t& top()
else
if (q1.empty() && !q2.empty())
}bool empty()
size_t size()
private:
queue
q1;queue
q2;};
bool ispoporder(const
int *ppush, const
int *ppop, int pushsize, int popsize)
}//3.若棧為空,則序列合法
return s.empty() == 1 ? true : false;
}
1.棧1用陣列的奇數字實現,棧2用陣列的偶數字實現。
2.把陣列的中間位置當做棧底,棧1的棧頂朝左走,棧2的棧頂朝右走。
3.陣列首元素位置作為棧1的棧底,陣列尾元素位置作為棧2的棧底,棧1和棧2的棧頂都朝陣列的中間走。
當棧1和棧2的資料個數相差較大時,第一種方法和第二種方法都會浪費陣列空間,而第三種方法可以避免空間的浪費,故在此只實現第三種方法。
templateclass twostack
~twostack()
void push1(const t& d)
void push2(const t& d)
void pop1()
}void pop2()
}t& top1()
t& top2()
size_t size1()
size_t size2()
bool empty1()
bool empty2()
void print1()
cout << endl;
}void print2()
cout << endl;
}protected:
void _createstack()
_top1 = 0;
_top2 = _capacity - 1;}}
void _checkcapacity()
//棧2的資料倒著拷
size_t j = _capacity - 1;
for (size_t i = oldcapacity - 1; i>_top2; i--)
delete _arr;
_arr = tmparr;
_top2 += _capacity / 2;}}
protected:
t* _arr; //陣列
size_t _top1; //棧1的棧頂
size_t _top2; //棧2的棧頂
size_t _capacity; //陣列的容量
};
力扣刷題筆記6 棧和佇列經典題目
題目1.刪除字串中的所有相鄰重複項 解題思路 1.分析特殊情況,當字串大小為空或者長度為1時,直接返回即可 2.將字串中的第乙個入棧,然後對後面的每乙個字元進行判斷 1 若當前的字母和棧頂的字母相同,則彈出棧頂的字母 2 若當前的字母和棧頂的字母不同,則放入當前的字母 3.最後將棧中的字元取出,組成...
棧和佇列之經典(上篇)
要完成下面關於棧和佇列的題目,首先要明白 棧的特性 後進先出 佇列的特性 先進先出 1 實現乙個棧,要求實現push 入棧 pop 出棧 min 返回最小值的操作 的時間複雜度為o 1 本題的關鍵是要得到棧的最小元素min,我們的第一反應可能是每次壓入乙個新的元素時,將棧裡所有元素排序,讓最小元素位...
棧和佇列之經典(下)
4 判斷元素出棧 入棧順序的合法性。如 入棧的序列 1,2,3,4,5 出棧序列為 4,5,3,2,1 是合法序列,入棧的序列 1,2,3,4,5 出棧序列為 1,5,3,2,4 是不合法序列 對於有關棧的問題,建立輔助棧解決會是很不錯的選擇。在本題中把輸入的入棧序列的數字依次壓入該輔助棧,並按照出...