[LeetCode] determine a binary tree

Posted by mazman on Sun, 16 Jan 2022 05:50:18 +0100

preface

This paper shows the topics related to determining a binary tree in LeetCode, which readers can use to write by dictation to check whether they are familiar with the relevant algorithms. The difficulty is medium.

LeetCode topic

Related topic types

Related links

105

Constructing binary tree from preorder and inorder traversal sequences (medium difficulty)

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

106

Constructing binary tree from middle order and post order traversal sequences (medium difficulty)

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

If readers don't know how to answer these questions, we suggest reading the author's previous blog: [binary tree] (III) determine a binary tree.

1, Related algorithm flow

Now we can summarize the above process of solving binary tree as the following recursive program:

Enter the Preorder array and Inorder array

1

If the number of preamble arrays is 0, NULL (termination condition) is returned directly

2

Determine the intermediate node root from the preamble array

3

If the number of preceding arrays is 1, root (termination condition) is returned directly

4

The cutting order array is leftInorder and rightInorder

5

The cutting preorder array is leftPreorder and rightPreorder

6

Call the program with leftInorder and leftPreorder

7

Call the program with rightInorder and rightPreorder

7

Return to root

It can be simply summarized as: 2 termination conditions, 2 cutting arrays and 2 recursive calls.

2, Relevant important API s

After knowing the algorithm flow, the difficulty in code implementation may be the selection of API for cutting arrays. We specially bring out the relevant implementations in Python and C + + separately for readers' comparison:

Related functions

Python code

C + + code

Remove the first element of the array

preorder.pop(0) preorder.erase(preorder.begin());

Remove the last element of the array

preorder.pop() 

preorder.pop_back();

Intercept [0,index)

leftPreorder = preorder[:index]

vector<int> leftPreorder(preorder.begin(), preorder.begin() + Index);

Intercept [index, end]

rightPreorder = preorder[index:]

vector<int> rightPreorder(preorder.begin() + Index, preorder.end());

Note that the above array concept refers to List in Python and vector in C + +.

3, Topic analysis

1. Constructing binary tree from preorder and inorder traversal sequences

Now that we know the algorithm flow, we can implement it in code.

Python version

Because the Python code is concise and not easily disturbed by the program syntax, we first write the process in Python and give it directly as follows:

def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        # 2 termination conditions
        if len(preorder)==0:
            return None
        rootValue = preorder[0]
        root = TreeNode(rootValue)
        if len(preorder)==1:
            return root
        # 2-cut array
        index = 0 # Cutting point
        for i in range(0,len(inorder)):# Traverse the ordered array to find the cutting point
            if inorder[i]==rootValue:
                index = i
                break
        leftInorder = inorder[:index]
        rightInorder = inorder[index+1:] # index is an intermediate node and cannot start from here
        index = len(leftInorder) # Change to the cut point of the preamble array
        preorder.pop(0) # Remove intermediate nodes
        leftPreorder = preorder[:index]
        rightPreorder = preorder[index:]
        # 2 recursive calls
        root.left = self.buildTree(leftPreorder,leftInorder)
        root.right = self.buildTree(rightPreorder,rightInorder)
        return root

C + + version

Next, we further give the C + + version, and pay attention to the comparison with the Python version:

TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        //2 termination conditions
        if (preorder.size() == 0) return NULL;
        int rootValue = preorder[0];
        TreeNode* root = new TreeNode(rootValue);
        if (preorder.size() == 1) return root;
        //2-cut array
        int Index;
        for (Index = 0; Index < inorder.size(); Index++) {
            if (inorder[Index] == rootValue) break;
        }
        vector<int> leftInorder(inorder.begin(), inorder.begin() + Index);
        vector<int> rightInorder(inorder.begin() + Index + 1, inorder.end() );
        Index = leftInorder.size();
        preorder.erase(preorder.begin());//Delete first element
        vector<int> leftPreorder(preorder.begin(), preorder.begin() + Index);
        vector<int> rightPreorder(preorder.begin() + Index, preorder.end());
        //2 recursive calls
        root->left = buildTree(leftPreorder,leftInorder );
        root->right = buildTree(rightPreorder,rightInorder);
        return root;
    }

2. Constructing binary tree from middle order and post order traversal sequences

Since the difference between post order array + mid order array and the previous one is mainly in determining the intermediate node, and the code difference is very small, we will not explain it in detail, but directly give the implementation results:

Python version

def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        #2 termination conditions
        if len(postorder)== 0: 
            return None
        rootValue = postorder[-1]
        root = TreeNode(rootValue)
        if len(postorder)== 1: 
            return root
        #2-step cut array
        Index=0;
        for i in range(0,len(inorder)):
            if inorder[i]==rootValue:
                Index=i
                break
        leftInorder=inorder[:Index]
        rightInorder=inorder[Index+1:]
        Index = len(leftInorder)
        postorder.pop()
        leftPostorder=postorder[:Index]
        rightPostorder=postorder[Index:]
        #Recursive call
        root.left = self.buildTree(leftInorder,leftPostorder)
        root.right = self.buildTree(rightInorder,rightPostorder)
        return root

C + + version

TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        //2 termination conditions
        if (postorder.size() == 0) return NULL;
        int rootValue = postorder[postorder.size()-1];
        TreeNode* root = new TreeNode(rootValue);
        if (postorder.size() == 1) return root;
        //2-cut array
        int Index;
        for (Index = 0; Index < inorder.size(); Index++) {
            if (inorder[Index] == rootValue) break;
        }
        vector<int> leftInorder(inorder.begin(), inorder.begin() + Index);
        vector<int> rightInorder(inorder.begin() + Index + 1, inorder.end() );
        Index = leftInorder.size();
        postorder.pop_back();//Delete last element
        vector<int> leftPostorder(postorder.begin(), postorder.begin() + Index);
        vector<int> rightPostorder(postorder.begin() + Index, postorder.end());
        //2 recursive calls
        root->left = buildTree(leftInorder,leftPostorder);
        root->right = buildTree(rightInorder,rightPostorder);
        return root;
    }

Topics: Python C++ Algorithm leetcode Binary tree