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; }