算法——二叉树中的深搜

目录

计算布尔二叉树的值

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

二叉树剪枝

验证二叉搜索树

[二叉搜索树中第 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);
    }
};
相关推荐
ZHOUPUYU5 小时前
PHP 8.3网关优化:我用JIT将QPS提升300%的真实踩坑录
开发语言·php
寻寻觅觅☆9 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
时代的凡人9 小时前
0208晨间笔记
笔记
fpcc9 小时前
并行编程实战——CUDA编程的Parallel Task类型
c++·cuda
偷吃的耗子9 小时前
【CNN算法理解】:三、AlexNet 训练模块(附代码)
深度学习·算法·cnn
l1t9 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
今天只学一颗糖9 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
赶路人儿10 小时前
Jsoniter(java版本)使用介绍
java·开发语言
化学在逃硬闯CS10 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
ceclar12310 小时前
C++使用format
开发语言·c++·算法