给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
示例 1:
输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/ \
4 5
/ \ \
5 4 7
注意: 合并必须从两个树的根节点开始。
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
//迭代先序
if(!t1)return t2;
else if(!t2)return t1;
stack<pair<TreeNode*,TreeNode*> > s;
pair<TreeNode*,TreeNode*> cur={t1,t2};
s.push(cur);
while(s.size()){
cur=s.top(),s.pop();
cur.first->val+=cur.second->val;
if(cur.first->left||cur.second->left){
if(!cur.first->left&&cur.second->left)
cur.first->left=new TreeNode(0);
else if(cur.first->left&&!cur.second->left)
cur.second->left=new TreeNode(0);
s.push(pair{cur.first->left,cur.second->left});
}
if(cur.first->right||cur.second->right){
if(!cur.first->right&&cur.second->right)
cur.first->right=new TreeNode(0);
else if(cur.first->right&&!cur.second->right)
cur.second->right=new TreeNode(0);
s.push(pair{cur.first->right,cur.second->right});
}
}
return t1;
}
};
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
//层序遍历补满二叉树
if(!t1)return t2;
else if(!t2)return t1;
queue<pair<TreeNode*,TreeNode*> > q;
pair<TreeNode*,TreeNode*> cur={t1,t2};
q.push(cur);
while(q.size()){
int qsize=q.size();
while(qsize--){
cur=q.front(),q.pop();
//start
cur.first->val+=cur.second->val;
//end
if(cur.first->left||cur.second->left){
if(!cur.first->left&&cur.second->left)
cur.first->left=new TreeNode(0);
else if(cur.first->left&&!cur.second->left)
cur.second->left=new TreeNode(0);
q.push(pair{cur.first->left,cur.second->left});
}
if(cur.first->right||cur.second->right){
if(!cur.first->right&&cur.second->right)
cur.first->right=new TreeNode(0);
else if(cur.first->right&&!cur.second->right)
cur.second->right=new TreeNode(0);
q.push(pair{cur.first->right,cur.second->right});
}
}
}
return t1;
}
}
给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
class Solution {
public:
int numTrees(int n) {
//递归
if(n==1)return 1;
else if(n==2)return 2;
else if(n==3)return 5;
int res=2*numTrees(n-1);
for(int i=1;i<=n-2;++i)
res+=numTrees(i)*numTrees(n-i-1);
return res;
}
};
class Solution {
public:
int numTrees(int n) {
//动态规划
if(n==1)return 1;
else if(n==2)return 2;
vector<int> v(n+1,0);
v[1]=1;
v[2]=2;
for(int i=3;i<=n;++i){
v[i]=v[i-1]<<1;
/*易错!!!!!受递归影响,想当然了,,,
for(int j=1;j<=n-2;++j)
v[i]+=v[j]*v[n-1-j];*/
for(int j=1;j<=i-2;++j)
v[i]+=v[j]*v[i-1-j];
}
return v[n];
}
};
发现转移方程可以更简单
class Solution {
public:
int numTrees(int n) {
//动态规划
if(n==1)return 1;
else if(n==2)return 2;
vector<int> v(n+1,0);
v[0]=1;
v[1]=1;
v[2]=2;
for(int i=3;i<=n;++i)
for(int j=0;j<=i-1;++j)
v[i]+=v[j]*v[i-1-j];
return v[n];
}
};
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
class Solution {
public:
bool isValidBST(TreeNode* root) {
/*
//迭代中序
if(!root)return true;
long long pre_val=LLONG_MIN;
stack<TreeNode*> S;
TreeNode* cur = root;
while(cur || S.size()){
while(cur){
S.push(cur);
cur=cur->left;
}
cur=S.top();
S.pop();
if(cur->val<=pre_val)return false;
pre_val=cur->val;
cur=cur->right;
}
return true; */
//morris中序遍历
if(!root)return true;
TreeNode *cur=root,*temp=nullptr;
long long pre_val=LLONG_MIN;
bool flag=true;
while(cur){
temp=cur->left;
if(temp){
while(temp->right&&temp->right!=cur)
temp=temp->right;
if(temp->right)
temp->right=nullptr;
else{
temp->right=cur;
cur=cur->left;
continue;
}
}
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
morris遍历时,此时如果还有线索未解锁则不能直接返回函数,否则报错
if(cur->val<=pre_val)return false;
*/
if(cur->val<=pre_val)
flag=false;
pre_val=cur->val;
cur=cur->right;
}
return flag;
}
};
morris中序dubug了好久,学习到了一点
morris遍历时,此时如果还有线索未解锁则不能直接返回函数,否则报错
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
class Solution {
public:
typedef vector<int>::iterator iter;
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.empty())return nullptr;
return helper(preorder.begin(),preorder.end(),inorder.begin(),inorder.end());
}
TreeNode* helper(iter a,iter b,iter c,iter d){
if(a>=b||c>=d)return nullptr;
int flag=*a;
iter it=find(c,d,flag);
TreeNode* root=new TreeNode(flag);
int diff=it-c;
root->left=helper(a+1,a+diff+1,c,it);
root->right=helper(a+diff+1,b,it+1,d);
return root;
}
};