Leetcode 3.15

二叉树

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

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

最重要的知识点:二叉树搜索树的中序遍历是升序的
方法一:我们只需存储升序遍历,返回升序遍历的结果即可。

/**
 * 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:
    vector<int> ans;
    int kthSmallest(TreeNode* root, int k) {
        dfs(root);
        return ans[k - 1];
    }
    void dfs(TreeNode* root) {
        if (root == nullptr) return;
        dfs(root->left);
        ans.push_back(root->val);
        dfs(root->right);    
    }
};

改进:我们还可以在找到答案后停止,不需要遍历整棵树。

/**
 * 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 ans;
    int kthSmallest(TreeNode* root, int k) {
        dfs(root, k);
        return ans;
    }
    void dfs(TreeNode* root, int &k) {
        if (root == nullptr) return;
        dfs(root->left, k);
        if (--k == 0) {
            ans = root->val;
            return;
        }
        dfs(root->right, k);    
    }
};

2.二叉树展开为链表

二叉树展开为链表
题目要求展开后与先序遍历相同,那么可以按照先序遍历再更改链表,在前序遍历结束之后更新每个节点的左右子节点的信息,找到前后元素在二叉树当中的位置,将二叉树展开为单链表。

/**
 * 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:
    void flatten(TreeNode* root) {
        vector<TreeNode*> ans;
        dfs(root, ans);
        for (int i = 1; i < ans.size(); i++) {
            //前一个节点
            auto *pre = ans.at(i - 1);
            //当前节点
            auto *cur = ans.at(i);
            pre->left = nullptr;
            pre->right = cur; 
        }
    }
    void dfs(TreeNode* root, vector<TreeNode*> &ans) {
        if (root == nullptr) return;
        ans.push_back(root);
        dfs(root->left, ans);
        dfs(root->right, ans);      
    }
};

思路二:更便捷的递归
参考
这个问题其实是分为三步:

  • 首先将根节点的左子树变成链表
  • 其次将根节点的右子树变成链表
  • 最后将变成链表的右子树放在变成链表的左子树的最右边

这就是一个递归的过程,递归的一个非常重要的点就是:不去管函数的内部细节是如何处理的,我们只看其函数作用以及输入与输出。对于函数flatten来说:

函数作用:将一个二叉树,原地将它展开为链表
输入:树的根节点
输出:无

/**
 * 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:
    void flatten(TreeNode* root) {
        if (root == nullptr) return;
        //展开左子树为链表
        flatten(root->left);
        //展开子树为链表
        flatten(root->right);
        auto l = root->left;
        auto r = root->right;
        //左子树置空
        root->left = nullptr;
        //左子树移动到右子树
        root->right = l;
        //指针指向右子树最后一个节点
        while (root->right != nullptr) root = root->right;
        //指向右子树
        root->right = r;
    }
};

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

从前序与中序遍历序列构造二叉树
根据前序和中序遍历我们可以确定二叉树的根节点,左子树和右子树,不断递归得到结果。比较复杂的是确定左右子树的边界。借助map来快速确定元素在inorder中的位置,这副图中的边界位置建议仔细推导。
需要注意的点:前序遍历中,左子树的右边界 需要借助 中序遍历中 左子树的个数 来辅助确定。
在这里插入图片描述

/**
 * 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* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n = preorder.size();
        if (!n) return nullptr;
        unordered_map<int, int> mp;
        for (int i = 0; i < n; i++) {
            mp[inorder[i]] = i;
        }
        return dfs(preorder, 0, n - 1, mp, 0, n - 1);
    }
    TreeNode* dfs(vector<int>& preorder, int preleft, int preright,
                unordered_map<int, int>& mp, int inleft, int intright) {
        if (preright < preleft || inleft > intright) return nullptr;
        TreeNode* ans = new TreeNode(preorder[preleft]);
        ans->left = dfs(preorder, preleft + 1, mp[preorder[preleft]] + preleft - inleft, 
                    mp, inleft, mp[preorder[preleft]] - 1);
        ans->right = dfs(preorder, mp[preorder[preleft]] + preleft - inleft + 1, preright, 
                    mp, mp[preorder[preleft]] + 1, intright);
        return ans;
    }

};

相关推荐

  1. leetcode 316. 去除重复字母

    2024-03-16 05:32:04       14 阅读
  2. Leetcode-316-去除重复字母

    2024-03-16 05:32:04       6 阅读
  3. LeetCode 31

    2024-03-16 05:32:04       32 阅读
  4. LEETCODE-DAY31

    2024-03-16 05:32:04       18 阅读
  5. LEETCODE-DAY35

    2024-03-16 05:32:04       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-16 05:32:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-16 05:32:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-16 05:32:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-16 05:32:04       20 阅读

热门阅读

  1. k8s admin 用户生成token

    2024-03-16 05:32:04       19 阅读
  2. 安装k8s集群

    2024-03-16 05:32:04       18 阅读
  3. 24计算机考研调剂 | 太原科技大学

    2024-03-16 05:32:04       21 阅读
  4. 【MySQL】mysqladmin、mysqlshow、mysqlcheck都是干嘛的?

    2024-03-16 05:32:04       21 阅读
  5. 【CSS】前端开发中的常见CSS样式问题解决方案

    2024-03-16 05:32:04       20 阅读
  6. 【构建工具】PostCSS快速配置

    2024-03-16 05:32:04       20 阅读
  7. HTML-DAY1

    2024-03-16 05:32:04       16 阅读
  8. C++(1): std::vector的使用

    2024-03-16 05:32:04       21 阅读
  9. 【 React 】对React refs的理解?应用场景?

    2024-03-16 05:32:04       21 阅读