LeetCode [105/106/112] construct binary tree from preorder and inorder traversal sequence, construct binary tree from inorder and postorder traversal sequence, path sum C/C++——Week 2 III

105. Construct Binary Tree from Preorder and Inorder Traversal Sequences

Title Description [Medium]:

Given two integer arrays preorder and inorder, where preorder is the preorder traversal of a binary tree and inorder is the inorder traversal of the same tree , construct a binary tree and return its root node.
Example 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

Output: [3,9,20,null,null,15,7]
1

Idea [recursion]:

We look at the tree in Example 1, we know that his preorder traversal sequence is: [3,9,20,15,7]; the inorder traversal sequence is: [9,3,15,20,7];
by observing We know that the root node is 3, the in-order traversal of the left subtree is [9], and the in-order traversal of the right subtree is [15, 20, 7]; through the pre-order traversal, the pre-order traversal of the left subtree is [9] ; Right subtree preorder traversal [20, 15, 7]. Then we can realize the construction of the binary tree by recursively traversing the left and right subtrees in preorder and inorder.
Note: After each recursion, it is necessary to find the subscript of the current root node in the inorder sequence. To improve efficiency, we can build a hash table to store the positions of all nodes in the inorder sequence. In this way, the search time can be changed from O(n)->O(1).

C++ code:

/**
 * 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 {
    
    
    //定义一个哈希表
    unordered_map<int, int> pos;

public:
    TreeNode* Build(const vector<int>& preorder, const vector<int>& inorder, int pl, int pr, int il, int ir) {
    
    
        if (pl > pr || il > ir) {
    
    
            return nullptr;
        }
        //左子树中的节点数目=当前节点在中序序列的位置-中序序列的起始下标
        int k = pos[preorder[pl]] - il;
        
        // 建立根节点        
        TreeNode* root = new TreeNode(preorder[pl]);

     
        // 递归地构造左子树,并连接到根节点
        // 先序遍历中「从 左边界+1 开始的 k」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
        root->left = Build(preorder, inorder, pl + 1, pl + k, il, il + k - 1);
        // 递归地构造右子树,并连接到根节点
        // 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
         root->right = Build(preorder, inorder, pl + k + 1, pr, il + k + 1, ir);
        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    
    
        //获取节点个数n
        int n = preorder.size();
        //通过哈希表来存储中序序列节点位置
        for (int i = 0; i < n; i++) {
    
    
            pos[inorder[i]] = i;
        }
        //调用二叉树的构建,切片操作
        return Build(preorder, inorder, 0, n - 1, 0, n - 1);
    }
};

Time/space complexity: O(n);

106. Construct Binary Tree from Inorder and Postorder Traversal Sequences

Title Description [Medium]:

Given two integer arrays inorder and postorder, where inorder is the inorder traversal of a binary tree and postorder is the postorder traversal of the same tree , please construct and return this binary tree.

Example 1:
Input: inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]

Output: [3,9,20,null,null,15,7]
2

Idea [recursion]:

This question takes Example 1 as an example. His inorder sequence is: [9,3,15,20,7], and the postorder sequence is [9,15,7,20,3]; according to the properties of these two sequences, We know that the last element of the postorder sequence is the root node, then through the inorder sequence, we know that the inorder traversal of the left subtree is [9]; the inorder traversal of the right subtree is [15,20,7]. So the postorder sequence of the left subtree is 9, and the postorder sequence of the right subtree is: [15, 7, 20]. We can recursively build left and right subtrees through these sequences, thus building a binary tree.

C++ code:

/**
 * 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 {
    
    
     //定义一个哈希表
    unordered_map<int, int> pos;
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
    
    
     //获取节点个数n
        int n = inorder.size();
        //通过哈希表来存储中序序列节点位置
        for (int i = 0; i < n; i++) {
    
    
            pos[inorder[i]] = i;
        }
        //调用二叉树的构建,切片操作
        return Build(inorder, postorder, 0, n - 1, 0, n - 1);
    }
       TreeNode* Build(vector<int>& inorder,  vector<int>& postorder, int il, int ir, int pl, int pr) {
    
    
        if (pl > pr || il > ir) {
    
    
            return nullptr;
        }
        //左子树中的节点数目=当前节点在中序序列的位置-后序序列的末下标
        int k = pos[postorder[pr]] - il;
        
        // 建立根节点        
        TreeNode* root = new TreeNode(postorder[pr]);

     
        // 递归地构造左子树,并连接到根节点
        // 先序遍历中「从 左边界 开始的 k - 1」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
        root->left = Build(inorder, postorder,il, il + k - 1, pl, pl + k - 1);
        // 递归地构造右子树,并连接到根节点
        // 先序遍历中「从 左边界+左子树节点数目+1 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位 到 右边界-1」的元素
         root->right = Build(inorder, postorder, il + k + 1, ir, pl + k , pr - 1);
        return root;
    }
};

Time/space complexity: O(n);

112. Path Sum

Title description [simple]:

You are given the root node root of the binary tree and an integer targetSum representing the target sum. Determine whether there is a path from the root node , and the sum of all node values ​​on this path is equal to the target and targetSum. Returns true if present; otherwise, returns false.

A leaf node is a node that has no child nodes.
Example 1:
3

Key:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22

Output: true
Explanation: The root node to leaf node path equal to the target sum is shown in the figure above.

Idea [recursion]:

The essence of the judgment of this question is to find a path whose path length is the value of target in the left subtree or right subtree.
Convert the title to: target == root->val

C++ code:

/**
 * 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 hasPathSum(TreeNode* root, int targetSum) {
    
    
        if(root == nullptr)
        return false;
        if(root -> left == nullptr && root -> right == nullptr)
        return root->val == targetSum;
        return hasPathSum(root->left,targetSum - root->val) || hasPathSum(root->right,targetSum - root->val);
    }
};

Time/space complexity: O(n);

Guess you like

Origin blog.csdn.net/Lailalalala/article/details/126161062