算法——二叉树中的深搜

目录

计算布尔二叉树的值

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

二叉树剪枝

验证二叉搜索树

[二叉搜索树中第 K 小的元素](#二叉搜索树中第 K 小的元素)

二叉树的所有路径


计算布尔二叉树的值

**思路:**要想得到结果,首先要知道根节点左子树的结果,根节点右子树的结果,然后两个结果结合根节点的运算符进行运算。根节点左子树的结果又可以分为左子树的结果和右子树的结果,然后这两个结果和左子树的根表示的运算符进行运算,依次类推,这个过程就是这道题递归的过程。

递归出口是遇到叶子节点直接返回结果就行。

代码:

cpp 复制代码
/**
 * 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){
            if(root->val == 0)
                return false;
            else
                return true;
        }

        bool left = evaluateTree(root->left);
        bool right = evaluateTree(root->right);

        if(root->val == 2)
            return left | right;
        else
            return left & right;
    }
};

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

**思路:**通过深度优先搜索(DFS)递归遍历二叉树,递归过程中携带当前路径已拼接的数字和(初始为 0),每访问一个节点就将前缀和乘以 10 并加上当前节点值以拼接新数字,当遍历到叶子节点时返回该路径的完整数字,非叶子节点则递归累加其左、右子树所有叶子节点返回的路径数字和,最终根节点返回的结果即为所有根到叶子节点路径的数字之和。

代码:

cpp 复制代码
/**
 * 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 prevsum)
    {
        prevsum = prevsum * 10 + root->val;
        if(root->left == NULL && root->right == NULL)
            return prevsum;

        int ret = 0;
        if(root->left) 
            ret += dfs(root->left, prevsum);
        if(root->right)
            ret += dfs(root->right, prevsum);

        return ret;
    }
};

二叉树剪枝

**思路:**递归搜索这颗树,当遇到叶子节点并且值为 0 的时候就将它从树上删除出去,因为移除的二叉树部分不能包含 1,所以遇到 0 不能直接删除,而是只有这个节点是叶子的时候才能删除。

代码:

cpp 复制代码
/**
 * 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)
            return nullptr;

        return root;
    }
};

验证二叉搜索树

**思路:**这道题可以利用二叉搜索树中序遍历有序的特点来解决,因为我们中序遍历这颗二叉树,然后使用一个全局变量把当前节点的前一个节点的值记录下来,如果当前节点的值小于等于前一个节点的值,他就不是一个搜索二叉树,只要有一个节点不符合,直接返回 false,后面的节点就没有必要判断了。(因为要中序遍历,所以先递归左子树,再判断当前节点,最后递归右子树)

代码:

cpp 复制代码
/**
 * 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 prev = LONG_MIN;
public:
    bool isValidBST(TreeNode* root) {
        if(root == nullptr)
            return true;

        bool left = isValidBST(root->left);
        if(left == false)
            return false;
        
        if(root->val <= prev)
            return false;
        prev = root->val;
        
        bool right = isValidBST(root->right);
        return right;
    }
};

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

**思路:**这道题可以利用搜索二叉树中序遍历有序的特点来解决,我们可以使用两个变量,一个用来记录当前遍历到第几个节点了,一个用来记录结果,因为是中序遍历其实就是按照节点的值从小到大遍历的,当遍历到第 K 个节点,直接将对应的值交给记录结果的变量即可。然后在主函数中返回结果。

代码:

cpp 复制代码
/**
 * 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 count = 0;
    int ret;
public:
    int kthSmallest(TreeNode* root, int k) {
        dfs(root, k);
        return ret;
    }

    void dfs(TreeNode* root, int k){
        if(root == nullptr || count >= k)
            return;
        dfs(root->left, k);
        count++;
        if(k == count)
            ret = root->val;
        dfs(root->right, k);
    }
};

二叉树的所有路径

**思路:**通过前序遍历就能得到二叉树的每一条路径,创建一个全局的变量存储每一条路径,递归函数中除了树节点这个参数外,额外添加一个 string 类型的参数,每次都将当前节点的值添加到这个 string 变量上,来存储这条路径都有哪些节点,当遇到一个叶子节点的时候,说明这条路径上的所有节点都已经找到了,将这个 string 变量添加到存放结果的 vector 中即可。

**细节问题:**string 变量不能使用引用,因为一条路径遍历完成后递归要向上回归,继续去找其他路径,回归过程中要把不属于接下来遍历的路径上的节点都从 string 变量中去除,不使用引用的情况下,我们就不用额外的操作来去除多余的节点,因为形参的改变不会影响到实参(具体看代码)。

代码:

cpp 复制代码
/**
 * 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> ret;
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        string tmp = "";
        dfs(root, tmp);
        return ret;
    }

    void dfs(TreeNode* root, string tmp){
        if(root->left == nullptr && root->right == nullptr){
            tmp += to_string(root->val);
            ret.push_back(tmp);
            return;
        }

        tmp += to_string(root->val) + "->";
        if(root->left)
            dfs(root->left, tmp);
        if(root->right)
            dfs(root->right, tmp);
    }
};
相关推荐
郭泽斌之心16 小时前
使用langsmith调试fay的prompt
经验分享·prompt·fay数字人
草原上唱山歌16 小时前
如何理解C语言中的指针?
c语言·开发语言·数据结构
MicroTech202516 小时前
微算法科技(NASDAQ: MLGO)使用机器学习保障量子安全下区块链高效可用
科技·算法·机器学习
m0_6625779716 小时前
C++中的模板方法模式
开发语言·c++·算法
csbysj202016 小时前
PHP 多维数组
开发语言
Aurora-silas16 小时前
从 Prompt Engineering 到 Harness Engineering:AI 工程能力的演进之路
人工智能·经验分享
We་ct16 小时前
LeetCode 33. 搜索旋转排序数组:O(log n)二分查找
前端·算法·leetcode·typescript·个人开发·二分·数组
墨白曦煜16 小时前
RocketMQ 实战:揭秘 @RocketMQMessageListener 的反序列化魔法与“万能”消费策略
开发语言·python·rocketmq
智驱力人工智能16 小时前
一盔一带AI抓拍系统能否破解非机动车执法取证难 骑行未戴头盔检测 电动车未戴头盔智能监测 摩托车头盔佩戴AI识别系统 边缘计算实时处理
人工智能·算法·yolo·目标检测·边缘计算
东方-教育技术博主16 小时前
AI 写一个可被 Blueprint 调用的角色技能系统
开发语言