文章目录
- 1.minimum-depth-of-binary-tree
- 2.maximum-depth-of-binary-tree
- 3.binary-tree-postorder-traversal
- 4.binary-tree-preorder-traversal
- 5. sum-root-to-leaf-numbers
- 6.same-tree
- 7. binary-tree-maximum-path-sum
- 8. populating-next-right-pointers-in-each-node(填充每个节点中的下一个右指针)
- 9. populating-next-right-pointers-in-each-node-ii
- 10.balanced-binary-tree
1.minimum-depth-of-binary-tree
求给定二叉树的最小深度。最小深度是指树的根结点到最近叶子结点的最短路径上结点的数量。
class Solution {
public:
int run(TreeNode *root) {
if(root==nullptr)
return 0;
int left = run(root->left);
int right = run(root->right);
if(left==0)
return 1+right;
else if(right==0)
return 1+left;
return 1+(left>right?right:left);
}
};
和求最大深度不同此处要考虑到一边树为空的情况
2.maximum-depth-of-binary-tree
求给定二叉树的最大深度,
最大深度是指树的根结点到最远叶子结点的最长路径上结点的数量。
int maxDepth(TreeNode *root) {
if(root==nullptr)
return 0;
int left = maxDepth(root->left);
int right = maxDepth(root->right);
return 1+(left>right?left:right);
}
3.binary-tree-postorder-traversal
求给定的二叉树的后序遍历。不过此处它让使用迭代方式求。
class Solution {
public:
void post(TreeNode *root, vector<int>& res){
stack<TreeNode*> node;
node.push(root);
while(!node.empty()){
TreeNode *tmp = node.top();
if(tmp->left==nullptr&&tmp->right==nullptr){
res.push_back(tmp->val);
node.pop();
}else{
if(tmp->right){
node.push(tmp->right);
tmp->right= nullptr;
}
if(tmp->left){
node.push(tmp->left);
tmp->left = nullptr;
}
}
}
}
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if(root)
post(root,res);
return res;
}
};
编码不认真,两眼泪汪汪
4.binary-tree-preorder-traversal
求给定的二叉树的前序遍历。用递归来解这道题太没有新意了,可以给出迭代的解法么?
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> res;
if(root==nullptr)
return res;
stack<TreeNode*> node;
TreeNode *tmp = root;
while(tmp || !node.empty()){
if(tmp){
res.push_back(tmp->val);
node.push(tmp);
tmp = tmp->left;
}else{
tmp = node.top();
node.pop();
tmp = tmp->right;
}
}
return res;
}
};
和后序遍历迭代版完全不一样的思路,先将左子树放到栈中,且每碰到一个节点就访问它,然后依次弹出每一个栈顶节点直到栈为空为止。
5. sum-root-to-leaf-numbers
给定一个仅包含数字0-9的二叉树,每一条从根节点到叶子节点的路径都可以用一个数字表示。
例如根节点到叶子节点的一条路径是1->2->3,那么这条路径就用123来代替。
class Solution {
private:
vector<int> sum;
public:
static int Sum(vector<int>& path){
int sum = 0;
for(int i=0;i<path.size();++i)
sum = sum*10 +path[i];
return sum;
}
void Pretr(TreeNode *root,vector<int> &path){
path.push_back(root->val);
if(root->left==nullptr && root->right==nullptr)
sum.push_back(Sum(path));
if(root->left)
Pretr(root->left,path);
if(root->right)
Pretr(root->right,path);
path.pop_back();
}
int sumNumbers(TreeNode *root) {
if(root==nullptr)
return 0;
vector<int> path;
Pretr(root,path);
return accumulate(sum.begin(),sum.end(),0);
}
};
与剑指offer上某题求路径和为给定值的路径有异曲同工之妙,递归是关键
6.same-tree
给出两个二叉树,请写出一个判断两个二叉树是否相等的函数。
判断两个二叉树相等的条件是:两个二叉树的结构相同,并且相同的节点上具有相同的值。
class Solution {
public:
bool isSameTree(TreeNode *p, TreeNode *q) {
if(p==nullptr && q==nullptr)
return true;
if(p==nullptr || q==nullptr)
return false;
if(p->val != q->val)
return false;
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
};
稍微变化一下就可以用于检查一颗树是否是对称树了,同类题型见第十题对称的二叉树,简直就是一起跳舞检查法
7. binary-tree-maximum-path-sum
给定一个二叉树,请计算节点值之和最大的路径的节点值之和是多少。
这个路径的开始节点和结束节点可以是二叉树中的任意节点
class Solution {
public:
int maxValue = INT32_MIN;
int maxPath(TreeNode *root) {
if(root==nullptr)
return 0;
int left = max(0,maxPath(root->left));
int right = max(0,maxPath(root->right));
maxValue = max(maxValue,left+root->val+right);
return root->val + max(left,right);
}
int maxPathSum(TreeNode *root) {
maxPath(root);
return maxValue;
}
};
8. populating-next-right-pointers-in-each-node(填充每个节点中的下一个右指针)
填充所有节点的next指针,指向它右兄弟节点。如果没有右兄弟节点,则应该将next指针设置为NULL。初始时,所有的next指针都为NULL.
- 方法一:层序遍历,时间复杂度:O(N),空间复杂度:O(N)
void connect(TreeLinkNode *root) {
if(root == nullptr)
return;
queue<TreeLinkNode *>ass;
ass.push(root);
while(!ass.empty()){
int size = ass.size();
for(int i=0;i<size;++i){
TreeLinkNode *node = ass.front();
ass.pop();
if(i<size-1){
node->next = ass.front();
}
if(node->left)
ass.push(node->left);
if(node->right)
ass.push(node->right);
}
}
}
- 方法二:使用已建立的
next
指针,时间复杂度:O(N),空间复杂度:O(1)
void connect(TreeLinkNode *root) {
if(root == nullptr)
return;
TreeLinkNode *leftmost = root;
while(leftmost->left){
TreeLinkNode *head = leftmost;
while(head){
head->left->next = head->right;
if(head->next != nullptr)
head->right->next = head->next->left;
head = head->next;
}
leftmost = leftmost->left;
}
}
值得庆幸的是这道题是完全二叉树的处理方法,所以使用层序遍历与复用上层还比较好处理,如果是一般二叉树哩?上面的算法还是有问题的,不过层序遍历没问题了。
9. populating-next-right-pointers-in-each-node-ii
继续思考第8题.这道题如果给定的树可以是任意的二叉树呢?你之前的给出的算法还有效吗?
class Solution {
public:
void connect(TreeLinkNode *root) {
if(root==nullptr)
return;
queue<TreeLinkNode*> qu;
qu.push(root);
while(!qu.empty()){
int size = qu.size();
for(int i=0;i<size;++i){
TreeLinkNode *tmp = qu.front();
qu.pop();
if(i<size-1)
tmp->next = qu.front();
if(tmp->left)
qu.push(tmp->left);
if(tmp->right)
qu.push(tmp->right);
}
}
}
};
状态不佳,第二种next指针法不想思考了。
10.balanced-binary-tree
判断给定的二叉树是否是平衡的
在这个问题中,定义平衡二叉树为每个节点的左右两个子树高度差的绝对值不超过1的二叉树
class Solution {
public:
bool Isbalance(TreeNode *root,int &depth){
if(root==nullptr){
depth = 0;
return true;
}
int left,right;
if(Isbalance(root->left,left)&&Isbalance(root->right,right)){
if(left-right>=-1 && left-right<=1){
depth = 1+(left>right?left:right);
return true;
}
}
return false;
}
bool isBalanced(TreeNode *root) {
int depth;
return Isbalance(root,depth);
}
};