二叉树的深搜_求根节点到叶节点数字之和_验证二叉搜索树_二叉树的所有路径

2331. 计算布尔二叉树的值

二叉树遍历可以用递归来解决,该问题的简单子问题是 知道左右孩子的值,再根据| &返回true/false。左子树右子树的值交给dfs解决。

终止条件就是到达叶子节点,即没有左右孩子,因为是完全二叉树 所以只需要判断一个孩子是否存在就可以。

/**
 * 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 evaluateTree(TreeNode* root) {
        if(root->left==nullptr)//因为完全二叉树判断一个就可以
            return root->val;
        bool left=evaluateTree(root->left);
        bool right=evaluateTree(root->right);
        if(root->val==2) return (left||right);
        else return (left&&right);
    }
};

129. 求根节点到叶节点数字之和

数字总和=每一条路径累加的数字

怎么算路径上累加的数字呢?

拿图中的5举例,遍历完左孩子8就应该返回1258,5和8是知道的,但12呢?这就需要我们传递参数。所以函数头不仅需要当前节点的指针,还要有累加的数字12.

每遍历一个节点就累加当前节点的val,如果为叶子节点就直接返回,有孩子继续递归累加数字。

所以简单的子问题就是从根节点开始累加val,并传给左右叶子节点,累加数字并返回。

左右孩子还有孩子就交给dfs完成,直到叶子节点返回。

/**
 * 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 sumNumbers(TreeNode* root) {
        return dfs(root,0);
    }
    int dfs(TreeNode*root,int presum)
    {
        presum=presum*10+root->val;
        if(root->left==nullptr&&root->right==nullptr)
            return presum;
        int sum=0;
        if(root->left) sum+=dfs(root->left,presum);
        if(root->right) sum+=dfs(root->right,presum);
        return sum;
    }
};

814. 二叉树剪枝

什么时候可以处理root为当前节点的子树呢?当然是后序遍历 完它的左右子树,获取左右子树的情况才能进行处理。

什么情况下可以删除它呢?左右子树+当前节点val==0时吗?可以,但不是最简单的情况。

我们后序遍历最先删除的肯定是为0的叶子结点,只要判断当前节点没有左右孩子+当前节点val==0就可以删除以当前节点为根的子树。

像上述左右子树+当前节点val==0,3个节点val都为0,根据上面的判断从叶子节点开始删也可以一个一个删除。

/**
 * 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* pruneTree(TreeNode* root) {
        if(root==nullptr)return nullptr;
        root->left=pruneTree(root->left);
        root->right=pruneTree(root->right);
        if(root->left==nullptr&&root->right==nullptr&&root->val==0)
        {
            //delete root;
            root=nullptr;
        }
        return root;
    }
};

98. 验证二叉搜索树

我们知道搜索二叉树的中序遍历是有序的。我们定义一个全局的变量prve记录上一个遍历数的大小,进行中序遍历,如果prve不是单调变化的,就说明它不是二叉搜索树。

判断左子树 判断当前节点 判断右子树

剪枝:

1.判断完左子树如果返回的false,就可以直接返回false

2.判断当前节点也是,是fasle就直接返回,不是就更新prve

/**
 * 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 {
    long prve=LONG_MIN;
public:
    bool isValidBST(TreeNode* root) {
        if(root==nullptr) return true;
        bool left=true,right=true;
        if(root->left) left=isValidBST(root->left);
        //剪枝
        if(left==false) return false;
        if(prve<root->val) prve=root->val;
        else return false;
        if(root->right) right=isValidBST(root->right);
        return left&&right;
    }
};

细节:因为节点最小值为INT_MIN,所以prve类型为logn 定义为LONG_MIN

230. 二叉搜索树中第 K 小的元素

和上道题一样,通过中序排序就可以找第k小的数。

建议定义两个全局变量,kq判断是否到第K个数,re记录要返回的值。

/**
 * 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 {
    int re=-1;
    int kq;
public:
    int kthSmallest(TreeNode* root, int k) {
        kq=k;
        dfs(root);
        return re;
    }
    void dfs(TreeNode* root)
    {
        if(root==nullptr||kq==0) return;
        dfs(root->left);
        if(--kq==0)
        {
            re=root->val;
            return;
        }
        dfs(root->right);
        return;
    }
};

257. 二叉树的所有路径

深度遍历二叉树时,用一个path字符串来记录经过的结点:不是叶子节点加val->,叶子节点加val,并返回。返回到哪里?可以定义一个全局的string数组,记录每条路径。

path字符串可以定义成全局的吗?

我们知道当访问到4叶子节点时,就要回溯到2,此时path:1->2->4变成1->2

如果定义成全局变量每次回溯都要进行手动恢复path。

因此我们可以把path当作参数传给递归函数,每个函数栈中都会保存一份path,当递归返回到上一层时,上一层的 path 会自动恢复成调用该递归的状态,无需额外处理。

从根节点开始进行深度优先遍历。

在遍历的过程中,维护一个当前路径列表,用来存储从根节点到当前节点的路径。

当遍历到一个叶子节点时,将当前路径添加到结果列表中。

遍历过程中,递归地处理左右子树,返回到父节点时,撤销之前的选择。

/**
 * 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 {
    vector<string> re;
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        string path="";
        dfs(root,path);
        return re;
    }
    void dfs(TreeNode*root,string path)
    {
        if(root==nullptr) return;
        if(root->left||root->right)
            path+=to_string(root->val)+"->";
        else
        {
            path+=to_string(root->val);
            re.push_back(path);
        }
        dfs(root->left,path);
        dfs(root->right,path);
            
    }
};
相关推荐
sysu631 小时前
59.螺旋矩阵Ⅱ python
数据结构·python·算法·leetcode·面试
星空_MAX2 小时前
C语言优化技巧--达夫设备(Duff‘s Device)解析
c语言·数据结构·c++·算法
自信的小螺丝钉5 小时前
【数据结构】线性数据结构——链表
数据结构·链表
TT哇5 小时前
【数据结构】二叉树
数据结构·leetcode
游王子5 小时前
Python学习(5):数据结构
开发语言·数据结构·python·学习
清风~徐~来5 小时前
【高阶数据结构】哈希表
数据结构·哈希算法·散列表
自信的小螺丝钉5 小时前
【数据结构】线性数据结构——栈
数据结构·
秋风&萧瑟5 小时前
【数据结构】单向循环链表的使用
数据结构·链表
南宫生6 小时前
力扣-数据结构-8【算法学习day.79】
java·数据结构·学习·算法·leetcode
挂机加载中6 小时前
7-58 输出不重复的数组元素
数据结构·算法