算法——二叉树中的深搜

目录

计算布尔二叉树的值

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

二叉树剪枝

验证二叉搜索树

[二叉搜索树中第 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);
    }
};
相关推荐
敲代码的嘎仔15 分钟前
实习日志day6--实习日志day6--title命名规范化&businessType纠正&补充缺失的@Log注解&报警与通信模块补充&产出阶段总结文档
java·开发语言·人工智能·git·python·实习·大二
Piko61428 分钟前
锐捷 VSU 虚拟化堆叠配置
运维·网络·笔记
江华森33 分钟前
Python 实现高德地图找房(一):环境搭建与数据爬虫
开发语言·爬虫·python
杜子不疼.34 分钟前
【Qt初识】信号槽(三):机制意义、断开连接与 Lambda 表达式
开发语言·数据库·qt
运行时记录1 小时前
prompt-optimizer skill
算法
万法若空1 小时前
【数据结构-哈希表】哈希表原理
数据结构·算法·散列表
退休倒计时2 小时前
【每日一题】LeetCode 437. 路径总和 III TypeScript
算法·leetcode·typescript
老迟到的茉莉2 小时前
Hermes 是谁?跟 Claude Code 差在哪
开发语言·python
BomanGe12 小时前
NSK W1501FA高速精密滚珠丝杠技术手册
数据库·经验分享·规格说明书
学逆向的2 小时前
汇编——内存
开发语言·汇编·算法·网络安全