包含min函數的棧
最小棧問題,這裏需要在class中維護兩個棧,一個棧用於正常的push、pop、top操作,另一個棧就是維護當前最小值的棧。
具體做法是,假設現在s2是最小棧,棧頂元素時當前最小值,此時push一個新的值value過來,我們判斷,如果value比最小棧的棧頂元素小,那麼,需要將value作爲新的最小值push到棧中,否則的話則把當前最小值作爲本次插入之後的最小值再push一次,即:s2.push(s2.top())
#include <iostream>
#include <stack>
using namespace std;
class Solution {
public:
void push(int value) {
s1.push(value);
if (s2.empty()||value < s2.top())
{
s2.push(value);
}
else
{
s2.push(s2.top());
}
}
void pop() {
s1.pop();
s2.pop();
}
int top() {
return s1.top();
}
int min() {
return s2.top();
}
private:
stack<int>s1;//正常的棧
stack<int>s2;//最小棧
};
棧的壓入、彈出序列
判斷壓入序列是否能夠得到彈出序列…
核心思路是需要一個輔助棧,如果彈出序列的當前數字剛好是棧頂元素,那麼直接彈出,否則的話繼續壓入,直到把需要彈出的數字壓入到棧中爲止。
這是一個循環操作,也即需要把滿足條件(棧頂元素等於彈出序列的當前元素)的所有值依次彈出。
如果把所有的數字都壓入完畢,最終彈出的個數卻比較少,導致棧中仍然存在元素,說明了不能完成彈出序列。
class Solution {
private:
stack<int>s;
public:
bool IsPopOrder(vector<int> pushV, vector<int> popV)
{
int j = 0;
for (int i = 0; i < pushV.size(); ++i)
{
s.push(pushV[i]);
while (!s.empty() && s.top() == popV[j])
{
s.pop();
++j;
}
}
if (s.empty())
return true;
else
return false;
}
};
從上往下打印二叉樹
二叉樹層序遍歷,BFS的思想,先入隊根節點,如果左子樹不爲空,入隊左子樹,如果右子樹不爲空則入隊右子樹。直到隊空爲止:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root) {
if (nullptr == root)
return vector<int>();
queue<TreeNode*>q;
q.push(root);
vector<int>result;
while (!q.empty())
{
TreeNode* r = q.front();
q.pop();
result.push_back(r->val);
if (r->left != nullptr)
q.push(r->left);
if (r->right != nullptr)
q.push(r->right);
}
return result;
}
};
二叉搜索樹的後序遍歷序列
二叉搜索樹,左子樹比根節點小,右子樹比根節點大。對於後序遍歷來說,根節點位於序列的最後,剩下的部分,分爲兩個部分,一部分比根小的是左子樹,一部分比根大的是是右子樹。
具體步驟:
1.先找到根(假設索引是r)
2.把右子樹序列找出來(從r-1往前搜索直到找到不滿足大於根節點的節點)
3.把左子樹序列找出來,在迭代中,只要有左子樹序列中的元素大於根,則返回false。
4.遞歸的對左右子樹進行1-3步驟。
#include <vector>
#include <iostream>
using namespace std;
class Solution {
private:
bool judge(vector<int>&a, int l, int r)
{
if (l >= r)
return true;
int j = r;//1.先找到根
int i,k;
for (i = r - 1; i >= l; --i)//把右子樹找出來
{
if (a[i] < a[r])
break;
}
for (k = i; k >= l; --k)//把左子樹找出來
{
if (a[k] > a[r])//只要有左子樹序列大於根,立即返回false
return false;
}
//如果都滿足,則需要遞歸找左右子樹
return judge(a,l,i) && judge(a,i+1,r-1);
}
public:
bool VerifySquenceOfBST(vector<int> sequence) {
if (sequence.size() == 0)
return false;
return judge(sequence, 0, sequence.size() - 1);
}
};
二叉樹種和爲某一值的路徑
根到葉子節點路徑和是否爲某一個target,把所有的路徑找出來。
這裏需要三個參數:
1.result 保存所有路徑
2.path 保存當前路徑
3.sum 保存當前和
具體算法思路:
1.計算當前sum值,如果當前sum值爲target的值,且當前節點爲葉子節點,則將當前路徑添加到結果中。
2.遞歸左子樹
3.遞歸右子樹
4.遞歸返回條件root爲空指針
class Solution {
private:
void dfs(vector<vector<int>>&r, vector<int>path, TreeNode * root, int sum,int target)
{
if (root == nullptr)
return;
path.push_back(root->val);
sum += root->val;
if ((root->left == nullptr&&root->right == nullptr) && (sum == target))
r.push_back(path);
dfs(r, path, root->left, sum, target);
dfs(r, path, root->right, sum, target);
}
public:
vector<vector<int> > FindPath(TreeNode* root, int expectNumber) {
if (nullptr == root)
return vector<vector<int>>();
vector<vector<int>>res;
vector<int>tmp;
dfs(res, tmp, root, 0,expectNumber);
return res;
}
};