【LeetCode 热题 100】二叉树的最大深度 / 翻转二叉树 / 二叉树的直径 / 验证二叉搜索树

⭐️个人主页:@小羊 ⭐️所属专栏:LeetCode 热题 100 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~

目录


二叉树的中序遍历

cpp 复制代码
class Solution {
    vector<int> res;
public:
    vector<int> inorderTraversal(TreeNode* root) {
        dfs(root);
        return res;
    }
    void dfs(TreeNode* root)
    {
        if (root == nullptr) return;
        dfs(root->left);
        res.push_back(root->val);
        dfs(root->right);
    }
};

二叉树的最大深度

cpp 复制代码
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        int left = maxDepth(root->left);
        int right = maxDepth(root->right);
        return left > right ? left + 1 : right + 1;
    }
};

翻转二叉树

cpp 复制代码
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == nullptr) return nullptr;
        TreeNode *left = invertTree(root->left);
        TreeNode *right = invertTree(root->right);
        root->left = right;
        root->right = left;
        return root;
    }
};

对称二叉树

cpp 复制代码
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return dfs(root->left, root->right);
    }
    bool dfs(TreeNode* left, TreeNode* right)
    {
        if (left && right)
        {
            if (left->val != right->val) return false;
            return dfs(left->left, right->right) && dfs(left->right, right->left);
        }
        else if (left != right) return false;
        else return true;
    }
};

二叉树的直径

cpp 复制代码
class Solution {
    int depth;
public:
    int diameterOfBinaryTree(TreeNode* root) {
        dfs(root);
        return depth - 1;
    }
    int dfs(TreeNode* root)
    {
        if (root == nullptr) return 0;
        int left = dfs(root->left);
        int right = dfs(root->right);
        depth = max(depth, left + right + 1);
        return max(left, right) + 1;
    }
};

二叉树的层序遍历

cpp 复制代码
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        queue<TreeNode*> q;
        if (root == nullptr) return res;
        q.push(root);
        while (q.size())
        {
            int sz = q.size();
            vector<int> tmp;
            while (sz--)
            {
                TreeNode *node = q.front();
                tmp.push_back(node->val);
                q.pop();
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            res.push_back(tmp);
        }
        return res;
    }
};

将有序数组转换为二叉搜索树

cpp 复制代码
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return dfs(nums, 0, nums.size() - 1);
    }
    TreeNode* dfs(vector<int>& nums, int l, int r)
    {
        if (l > r) return nullptr;
        int mid = l + (r - l) / 2;
        TreeNode* node = new TreeNode(nums[mid]);
        node->left = dfs(nums, l, mid - 1);
        node->right = dfs(nums, mid + 1, r);
        return node;
    }
};

验证二叉搜索树

递归遍历。

cpp 复制代码
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        return dfs(root, LONG_MIN, LONG_MAX);
    }
    bool dfs(TreeNode* root, long min_val, long max_val)
    {
        if (root == nullptr) return true;
        if (root->val <= min_val || root->val >= max_val) return false;
        return dfs(root->left, min_val, root->val) 
            && dfs(root->right, root->val, max_val);
    }
};

前序遍历。

cpp 复制代码
class Solution {
    long prev = LONG_MIN;
public:
    bool isValidBST(TreeNode* root) {
        if (root == nullptr) return true;
        if (isValidBST(root->left) == false) return false;
        if (root->val <= prev) return false;
        prev = root->val; 
        return isValidBST(root->right);
    }
};

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

cpp 复制代码
class Solution {
    int res, cnt;
public:
    int kthSmallest(TreeNode* root, int k) {
        cnt = k;
        dfs(root);
        return res;
    }
    void dfs(TreeNode* root)
    {
        if (root == nullptr) return;
        dfs(root->left);
        if (--cnt == 0) 
        {
            res = root->val;
            return;
        }
        dfs(root->right);
    }
};

二叉树的右视图

从右往左层序遍历,每次都只拿队头节点的值。

cpp 复制代码
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int> res;
        if (root == nullptr) return res;
        queue<TreeNode*> q;
        q.push(root);
        while (q.size())
        {
            res.push_back(q.front()->val);
            int sz = q.size();
            while (sz--)
            {
                TreeNode* node = q.front();
                q.pop();
                if (node->right) q.push(node->right);
                if (node->left) q.push(node->left);
            }
        }
        return res;
    }
};

二叉树展开为链表

方法一:在前序遍历的过程中把节点存起来,结束后在处理每个节点的指向。

cpp 复制代码
class Solution {
public:
    void flatten(TreeNode* root) {
        vector<TreeNode*> vt;
        dfs(root, vt);
        for (int i = 1; i < vt.size(); i++)
        {
            TreeNode* prev = vt[i - 1], *cur = vt[i];
            prev->left = nullptr;
            prev->right = cur;
        }
    }
    void dfs(TreeNode* root, vector<TreeNode*>& vt)
    {
        if (root)
        {
            vt.push_back(root);
            dfs(root->left, vt);
            dfs(root->right, vt);
        }
    }
};

方法二:寻找前驱结点法。

在前序遍历的过程中,如果当前节点的左子树不为空,则遍历到当前节点的右子树的前一个节点为:当前节点左子树中最右的那个节点。我们在遍历的过程中找到这个前驱结点,将当前节点的右子树拼接到这个前驱节点的右节点上,然后将当前节点的左子树拼接到当前节点的右子树上,最后当前节点左子树置空。

cpp 复制代码
class Solution {
public:
    void flatten(TreeNode* root) {
        TreeNode* cur = root;
        while (cur)
        {
            if (cur->left)
            {
                auto prev = cur->left;
                while (prev->right) prev = prev->right;
                prev->right = cur->right;
                cur->right = cur->left;
                cur->left = nullptr;
            }
            cur = cur->right;
        }
    }
};

从前序与中序遍历序列构造二叉树

根据前序遍历依次找到根节点,通过找到的根节点找到中序遍历中根节点的位置,从而划分出 [左子树] [根节点] [右子树]。

用哈希表存储中序遍历的值和下标映射关系,以至于能在找到根节点后直接拿到根节点在中序遍历中的位置,然后根据中序遍历的位置递归构建左子树和右子树。

cpp 复制代码
class Solution {
    unordered_map<int, int> index;
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for (int i = 0; i < inorder.size(); i++)
        {
            index[inorder[i]] = i;
        }
        return dfs(preorder, 0, 0, inorder.size() - 1);
    }
    TreeNode* dfs(vector<int>& preorder, int root, int l, int r)
    {
        if (l > r) return nullptr;
        TreeNode* node = new TreeNode(preorder[root]);
        int id = index[preorder[root]];
        node->left = dfs(preorder, root + 1, l, id - 1);
        node->right = dfs(preorder, root + id - l + 1, id + 1, r);
        return node;
    }
};

路径总和

cpp 复制代码
class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) return false;
        if (root->left == nullptr && root->right == nullptr) 
        {
            return targetSum == root->val;
        }
        return hasPathSum(root->left, targetSum - root->val) 
            || hasPathSum(root->right, targetSum - root->val);
    }
};

路径总和 II

cpp 复制代码
class Solution {
    vector<vector<int>> res;
    vector<int> path;
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        dfs(root, targetSum);
        return res;
    }
    void dfs(TreeNode* root, int t)
    {
        if (root == nullptr) return;
        path.push_back(root->val);
        if (root->left == nullptr && root->right == nullptr && t == root->val)
        {
            res.push_back(path);
        }
        dfs(root->left, t - root->val);
        dfs(root->right, t - root->val);
        path.pop_back(); // 回溯
    }
};

路径总和 III

cpp 复制代码
class Solution {
    using ll = long long;
    unordered_map<ll, int> pre_cnt; // 记录前缀和及其出现次数
    int t;
public:
    int pathSum(TreeNode* root, int targetSum) {
        t = targetSum;
        pre_cnt[0] = 1; // 前缀和恰好等于目标值
        return dfs(root, 0);
    }
    int dfs(TreeNode* root, ll sum) {
        if (root == nullptr) return 0;
        sum += root->val;
        int count = pre_cnt[sum - t];
        pre_cnt[sum]++;
        count += dfs(root->left, sum);
        count += dfs(root->right, sum);
        pre_cnt[sum]--;
        return count;
    }
};

  • <>
cpp 复制代码

  • <>
cpp 复制代码

本篇文章的分享就到这里了,如果您觉得在本文有所收获,还请留下您的三连支持哦~

相关推荐
上不如老下不如小3 分钟前
2025年第七届全国高校计算机能力挑战赛 决赛 Java组 编程题汇总
java·python·算法
兩尛7 分钟前
查找接口成功率最优时间段 (c卷)
c语言·开发语言·算法
再__努力1点7 分钟前
【59】3D尺度不变特征变换(SIFT3D):医学影像关键点检测的核心算法与实现
人工智能·python·算法·计算机视觉·3d
小白量化10 分钟前
量化研究--上线完成强大的金融数据库3.0系统
数据库·人工智能·python·算法·金融·量化·qmt
roman_日积跬步-终至千里10 分钟前
【计算机算法与设计(8)】最小生成树算法(Kruskal 算法和 Prim 算法)
算法
e疗AI产品之路10 分钟前
心电QRS波形识别之Pan-Tompkins算法介绍
算法·pan-tompkins
一碗白开水一11 分钟前
【论文阅读】DALL-E 123系列论文概述
论文阅读·人工智能·pytorch·深度学习·算法
Yupureki13 分钟前
《算法竞赛从入门到国奖》算法基础:入门篇-模拟
c语言·数据结构·c++·算法·visual studio
资深web全栈开发13 分钟前
LeetCode 3583: 统计特殊三元组 - 从 O(n³) 到 O(n) 的顿悟之旅
算法·leetcode
早睡的叶子14 分钟前
AI 编译器中的 SRAM 内存分配管理算法调研
前端·人工智能·算法