二叉树的递归问题

这篇博客介绍了如何使用深度优先和广度优先搜索求解二叉树的最大深度,以及判断二叉树是否对称。此外,还提供了寻找路径总和的递归和迭代解决方案,并探讨了二叉树节点连接问题。文章通过实例代码详细解释了每个算法的实现过程。
摘要由CSDN通过智能技术生成
二叉树层数

深度搜索:

class Solution {
public:
    int maxDepth(TreeNode* root) {
    if(!root)return 0;
    return (max(maxDepth(root->left),maxDepth(root->right))+1);
    }
};

广度搜索:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        int ret=0;
        if(!root) return 0;
        queue<TreeNode*>bfs;
        bfs.push(root);
        TreeNode*tmp=root;
        while(!bfs.empty()){
            int sz=bfs.size();        
            for(int i=0;i<sz;i++){
                tmp=bfs.front();
                bfs.pop();
                if(tmp->left!=nullptr)bfs.push(tmp->left);
                if(tmp->right!=nullptr)bfs.push(tmp->right);            
            }
            ret++;
           // cout<<ret<<endl;
        }
        return ret;
    }
};
对称判断

1.递归

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return check(root,root);
    }
    bool check(TreeNode*left,TreeNode*right){
        if(!left&&!right)return true;
        if((!left&&right)||(left&&!right))return false;//if (!p || !q) return false;简化写法
        return left->val==right->val && check(left->left,right->right) && check(left->right,right->left);
    }
};

2.迭代

  • ,这个有问题,再仔细写一边
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return check(root,root);
    }
    bool check(TreeNode*l,TreeNode*r){
        queue<TreeNode*>q;
        q.push(l);
        q.push(r);
       // if(!l&&!r)return true;
       
        while(!q.empty()){
            l=q.front();q.pop();
            r=q.front();q.pop();
         
            if(!l&&!r)continue;//这次循环结束,跳到循环开始
             else if((!l||!r) &&( l->val!=r->val))return false;
           
                q.push(l->left);
                q.push(l->right);
                q.push(r->right);
                q.push(r->left);
            
        }
        return true;
    }
};

感冒让我短路

是否有总和为x的一条路径
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public://递归
    bool hasPathSum(TreeNode* root, int targetSum) {
if(!root) return false;
else if(!root->left&&!root->right)return targetSum==root->val;
else return hasPathSum(root->left,targetSum-root->val)||hasPathSum(root->right,targetSum-root->val);
    }
};

队列的写法,注意叶子节点是没有子节点的结点

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        queue<TreeNode*>nodelist;
        queue<int>valtmp;
        if(!root) return false;
        nodelist.push(root);
        valtmp.push(root->val);
        while(!nodelist.empty()){
            TreeNode*tmpnode=nodelist.front();
            nodelist.pop();
            int tmpsum=valtmp.front();
            valtmp.pop();
            if(tmpsum==targetSum&&tmpnode->left==nullptr&&tmpnode->right==nullptr)return true;
            else{
                cout<<tmpsum<<endl;
                if(tmpnode==nullptr)continue;
                else{
                    if(tmpnode->left){
                    nodelist.push(tmpnode->left);
                    valtmp.push(tmpnode->left->val+tmpsum);
                    }
                    if(tmpnode->right){
                    nodelist.push(tmpnode->right);
                    valtmp.push(tmpnode->right->val+tmpsum);
                    }

                }
            }
        }
        return false;
    }
};

注:迭代器给vector初始化左闭右开,如(b.begin(),b.end())是不包括end指向的元素的。

生成二叉树
106. 从中序与后序遍历序列构造二叉树
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0&&postorder.size()==0)return nullptr;
 return bulid(inorder,postorder);
    }
    TreeNode*  bulid(vector<int>& inorder, vector<int>& postorder){
        if(postorder.size()==0)return nullptr;//一定要有空的跳出语句
        int rootval=postorder[postorder.size()-1];
        TreeNode*root=new TreeNode(rootval);
        if(inorder.size()>1){
        int index=0;
        //查找后序的最后一个元素(根)对应的在中序中的序号,分隔开左右
        for(index=0;index<inorder.size();index++){
           if(inorder[index]==rootval)break;
       }
        vector<int>leftinorder(inorder.begin(),inorder.begin()+index);
        vector<int>leftpostorder(postorder.begin(),postorder.begin()+index);
    
       postorder.resize(postorder.size() - 1);//最后一个元素以及构建new 可以删去了

        vector<int>rightinorder(inorder.begin()+index+1,inorder.end());
        vector<int>rightpostorder(postorder.begin()+index,postorder.end());
        root->left=bulid(leftinorder,leftpostorder);
        root->right=bulid(rightinorder,rightpostorder);
        }
        return root;
    }
};
116. 填充每个节点的下一个右侧节点指针

联想层次遍历

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        if(root==nullptr)return root;
        queue<Node*>q;
        q.push(root);
        while(!q.empty()){
            int size=q.size();
            for(int i=0;i<size;i++){
            Node*tmp=q.front();q.pop();
            if(i<size-1)tmp->next=q.front();
            if(tmp->left!=nullptr){
                q.push(tmp->left);
            }
            if(tmp->right!=nullptr){
                q.push(tmp->right);
            }
            }
        }
        return root;
    }
};

注:lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。也就是说,使用该函数在指定范围内查找某个目标值时,最终查找到的不一定是和目标值相等的元素,还可能是比目标值大的元素。

lower_bound() 函数定义在<algorithm>头文件中,其语法格式有 2 种,分别为:
//在 [first, last) 区域内查找不小于 val 的元素ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,const T& val);
236. 二叉树的最近公共祖先

具体思路:
(1) 如果当前结点 root 等于 NULL,则直接返回 NULL
(2) 如果 rootroot 等于 p或者 q,那这棵树一定返回 p 或者 q
(3) 然后递归左右子树,因为是递归,使用函数后可认为左右子树已经算出结果,用 left和 right 表示
(4) 此时若left为空,那最终结果只要看 right;若 right 为空,那最终结果只要看 left
(5) 如果 left和 right 都非空,因为只给了 p 和 q 两个结点,都非空,说明一边一个,因此 root是他们的最近公共祖先
(6) 如果 left 和 right 都为空,则返回空(其实已经包含在前面的情况中了)

作者:Wilson79
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/c-jing-dian-di-gui-si-lu-fei-chang-hao-li-jie-shi-/
来源:力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root==nullptr)return nullptr;
        if(root==p||root==q)return root;
        TreeNode*left=lowestCommonAncestor(root->left,p,q);//判断左子树是否是公共节点,一旦找到一个节点是p||q,再去递归同层另一侧子树
        TreeNode*right=lowestCommonAncestor(root->right,p,q);
        if(!left)return right;
        if(!right)return left;
        if(right&&left)return root;
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值