155. 最小棧
設計一個支持 push,pop,top 操作,並能在常數時間內檢索到最小元素的棧。
push(x) -- 將元素 x 推入棧中。
pop() -- 刪除棧頂的元素。
top() -- 獲取棧頂元素。
getMin() -- 檢索棧中的最小元素。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
思路一:
解法1:用兩個棧實現最小棧功能
一個棧s存放數據,另一個棧min存放前棧中最小的數據
class MinStack {
public:
stack<int> s;//數據棧
stack<int> min;//輔助棧
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
s.push(x);
if(min.empty()||x<=min.top())
{
min.push(x);
}
}
void pop() {
if(s.top()==min.top())
min.pop();
s.pop();
}
int top() {
return s.top();
}
int getMin() {
return min.top();
}
};
解法2:一個棧實現
棧中兩個數據位合成一個單元,第一個數據位存放當前數據到末尾的最小值,第二個數據位存放當前數據
class MinStack {
public:
/** initialize your data structure here. */
stack<int> s;
MinStack() {
}
void push(int x) {
if(s.empty())
{
s.push(x);
s.push(x);
}
else
{
int temp=s.top();
s.push(x);
if(x<temp)
{
s.push(x);
}
else
{
s.push(temp);
}
}
}
void pop() {
s.pop();
s.pop();
}
int top() {
int temp=s.top();
s.pop();
int top=s.top();
s.push(temp);
return top;
}
int getMin() {
return s.top();
}
};
作者:chenlele
鏈接:https://leetcode-cn.com/problems/min-stack/solution/zui-xiao-zhan-by-gpe3dbjds1/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
我的:
class MinStack {
public:
stack<int> s;//數據棧
stack<int> min;//輔助棧
/** initialize your data structure here. */
MinStack() {
}
void push(int x)
{
s.push(x);
if(min.empty()||x <= min.top())
{
min.push(x);
}
}
void pop()
{
if(s.top() == min.top())
{
min.pop();
}
s.pop();
}
int top() {
return s.top();
}
int getMin() {
return min.top();
}
};
/**
* 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();
*/
94. 二叉樹的中序遍歷
給定一個二叉樹,返回它的中序遍歷。
示例:
進階:遞歸算法很簡單,你可以通過迭代算法完成嗎?
思路一:二叉樹的中序遍歷 - 迭代法
解題思路:
• 前序遍歷迭代算法
• 後序遍歷迭代算法
o 第一種方法
o 第二種方法
• 中序遍歷迭代算法
前序遍歷迭代算法:
二叉樹的前序遍歷
二叉樹的遍歷,整體上看都是好理解的。
三種遍歷的迭代寫法中,數前序遍歷最容易理解。
遞歸思路:先樹根,然後左子樹,然後右子樹。每棵子樹遞歸。
在迭代算法中,思路演變成,每到一個節點 A,就應該立即訪問它。
因爲,每棵子樹都先訪問其根節點。對節點的左右子樹來說,也一定是先訪問根。
在 A 的兩棵子樹中,遍歷完左子樹後,再遍歷右子樹。
因此,在訪問完根節點後,遍歷左子樹前,要將右子樹壓入棧。
思路:
代碼:
後序遍歷迭代算法:
二叉樹的後序遍歷
有兩種方法。第一種比第二種要容易理解,但多了個結果逆序的過程。
第一種方法:
我們可以用與前序遍歷相似的方法完成後序遍歷。
後序遍歷與前序遍歷相對稱。
思路: 每到一個節點 A,就應該立即訪問它。 然後將左子樹壓入棧,再次遍歷右子樹。
遍歷完整棵樹後,結果序列逆序即可。
思路:
代碼:
第二種方法:
按照左子樹-根-右子樹的方式,將其轉換成迭代方式。
思路:每到一個節點 A,因爲根要最後訪問,將其入棧。然後遍歷左子樹,遍歷右子樹,最後返回到 A。
但是出現一個問題,無法區分是從左子樹返回,還是從右子樹返回。
因此,給 A 節點附加一個標記T。在訪問其右子樹前,T 置爲 True。之後子樹返回時,當 T 爲 True表示從右子樹返回,否則從左子樹返回。
當 T 爲 false 時,表示 A 的左子樹遍歷完,還要訪問右子樹。
同時,當 T 爲 True 時,表示 A 的兩棵子樹都遍歷過了,要訪問 A 了。並且在 A 訪問完後,A 這棵子樹都訪問完成了。
思路:
代碼:
中序遍歷迭代算法:
二叉樹的中序遍歷
思路:每到一個節點 A,因爲根的訪問在中間,將 A 入棧。然後遍歷左子樹,接着訪問 A,最後遍歷右子樹。
在訪問完 A 後,A 就可以出棧了。因爲 A 和其左子樹都已經訪問完成。
思路:
代碼:
作者:jason-2
鏈接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/die-dai-fa-by-jason-2/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
我的:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root)
{
stack<TreeNode*> S;
vector<int> v;
TreeNode* rt = root;
while(rt || S.size()){
while(rt){
S.push(rt);
rt=rt->left;
}
rt=S.top();S.pop();
v.push_back(rt->val);
rt=rt->right;
}
return v;
}
};