算法——二叉树中的深搜

目录

计算布尔二叉树的值

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

二叉树剪枝

验证二叉搜索树

[二叉搜索树中第 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);
    }
};
相关推荐
CoovallyAIHub2 小时前
Moonshine:比 Whisper 快 100 倍的端侧语音识别神器,Star 6.6K!
深度学习·算法·计算机视觉
CoovallyAIHub3 小时前
速度暴涨10倍、成本暴降6倍!Mercury 2用扩散取代自回归,重新定义LLM推理速度
深度学习·算法·计算机视觉
CoovallyAIHub3 小时前
实时视觉AI智能体框架来了!Vision Agents 狂揽7K Star,延迟低至30ms,YOLO+Gemini实时联动!
算法·架构·github
CoovallyAIHub4 小时前
开源:YOLO最强对手?D-FINE目标检测与实例分割框架深度解析
人工智能·算法·github
CoovallyAIHub4 小时前
OpenClaw:从“19万星标”到“行业封杀”,这只“赛博龙虾”究竟触动了谁的神经?
算法·架构·github
刀法如飞4 小时前
程序员必须知道的核心算法思想
算法·编程开发·算法思想
徐小夕6 小时前
pxcharts Ultra V2.3更新:多维表一键导出 PDF,渲染兼容性拉满!
vue.js·算法·github
CoovallyAIHub7 小时前
OpenClaw一脚踩碎传统CV?机器终于不再只是看世界
深度学习·算法·计算机视觉
CoovallyAIHub7 小时前
仅凭单目相机实现3D锥桶定位?UNet-RKNet破解自动驾驶锥桶检测难题
深度学习·算法·计算机视觉
zone77397 小时前
002:RAG 入门-LangChain 读取文本
后端·算法·面试