二叉树:构造二叉树

LeetCode106. 从中序与后序遍历序列构造二叉树

https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

根据一棵树的中序遍历与后序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7
思路

以后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来在切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。

图片

代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution 
{
public:
    TreeNode* dfs(vector<int>& inorder, int inorderBegin, int inorderEnd,
                  vector<int>& postorder, int postorderBegin, int postorderEnd)
    {
        if (postorderEnd - postorderBegin == 0) return nullptr;

        int rootVal = postorder[postorderEnd - 1];
        TreeNode* root = new TreeNode(rootVal);
        if (postorderEnd - postorderBegin == 1) return root;

        int index;
        for (index = 0; index < inorderEnd && inorder[index] != rootVal; ++index);

        int leftInorderBegin = inorderBegin;
        int leftInorderEnd = index;
        int rightInorderBegin = index + 1;
        int rightInorderEnd = inorderEnd;

        int leftPostorderBegin = postorderBegin;
        int leftPostorderEnd = postorderBegin + index - inorderBegin;
        int rightPostorderBegin = postorderBegin + index - inorderBegin;
        int rightPostorderEnd = postorderEnd - 1;

        root->left = 
        dfs(inorder, leftInorderBegin, leftInorderEnd, postorder, leftPostorderBegin, leftPostorderEnd);
        root->right = 
        dfs(inorder, rightInorderBegin, rightInorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);

        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
    {
        return dfs(inorder, 0 , inorder.size(), postorder, 0, postorder.size());    
    }
};

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

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

注意:
你可以假设树中没有重复的元素。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7
思路

与LeetCode106. 从中序与后序遍历序列构造二叉树思路相同,具体思路见代码。

代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution 
{
public:
    TreeNode* dfs(vector<int>& inorder, int inorderBegin, int inorderEnd,
                  vector<int>& preorder, int preorderBegin, int preorderEnd)
    {
        if (preorderEnd - preorderBegin == 0) return nullptr;

        int rootVal = preorder[preorderBegin];
        TreeNode* root = new TreeNode(rootVal);
        if (preorderEnd - preorderBegin == 1) return root;

        int index;
        for (index = 0; index < inorderEnd && inorder[index] != rootVal; ++index);

        int leftInorderBegin = inorderBegin;
        int leftInorderEnd = index;
        int rightInorderBegin = index + 1;
        int rightInorderEnd = inorderEnd;

        int leftPreorderBegin = preorderBegin + 1;
        int leftPreorderEnd = preorderBegin + 1 + index - inorderBegin;
        int rightPreorderBegin = preorderBegin + 1 + index - inorderBegin;
        int rightPreorderEnd =preorderEnd;

        root->left = 
        dfs(inorder, leftInorderBegin, leftInorderEnd, preorder, leftPreorderBegin, leftPreorderEnd);
        root->right = 
        dfs(inorder, rightInorderBegin, rightInorderEnd, preorder, rightPreorderBegin, rightPreorderEnd);

        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
        return dfs(inorder, 0, inorder.size(), preorder, 0, preorder.size());
    }
};

LeetCode654. 最大二叉树

https://leetcode-cn.com/problems/maximum-binary-tree/

给定一个不含重复元素的整数数组 nums 。一个以此数组直接递归构建的 最大二叉树 定义如下:

  1. 二叉树的根是数组 nums 中的最大元素。
  2. 左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。
  3. 右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。

返回有给定数组 nums 构建的 最大二叉树

在这里插入图片描述

输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
    - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
        - 空数组,无子节点。
        - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
            - 空数组,无子节点。
            - 只有一个元素,所以子节点是一个值为 1 的节点。
    - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
        - 只有一个元素,所以子节点是一个值为 0 的节点。
        - 空数组,无子节点。
思路

图片

遍历数组找到最大值作为分割点,再对分割点的左数组和右数组进行递归操作。

代码
/**
 * 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 
{
private:
    TreeNode* dfs(vector<int>& nums, int left, int right)
    {
        if (right - left == 0) return nullptr;

        //分割点下标:maxValueIndex
        int maxValueIndex = left;
        for (int i = left + 1; i < right; ++i)
        {
            if (nums[i] > nums[maxValueIndex])
            {
                maxValueIndex = i;
            }
        }
        TreeNode* root = new TreeNode(nums[maxValueIndex]);
        if (right - left == 1) return root;

        //左闭右开:[left, maxValueIndex)
        root->left = dfs(nums, left, maxValueIndex);
        //左闭右开:[maxValueIndex + 1, right)
        root->right = dfs(nums, maxValueIndex + 1, right);

        return root;
    }

public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) 
    {
        return dfs(nums, 0, nums.size());
    }
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值