重建二叉树(Python and C++解法)

题目:

  输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

    3
   / \
 9  20
     / \
  15 7

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof

思路:

        3      9     【 20      15      7    】

   根节点             左子树                                         右子树

  9      3     【 15      20      7    】

 左子树         根节点                                         右子树

  根据前序遍历,可以确定根节点;根据中序遍历,可以确定左子树节点和右子树节点,同时可以确定子树节点的前序遍历和中序遍历结果,因此根据节点使用递归方法建立子树。

Python解法:

 1 # 定义二叉树
 2 class TreeNode:
 3     def __init__(self, x):  # self相当于类的实例
 4         self.val = x
 5         self.left = None
 6         self.right = None
 7 
 8 
 9 class Solution:
10     def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
11         if not preorder or not inorder or len(preorder) != len(inorder):  # 考虑异常条件
12             return None
13         root = preorder[0]
14         rootNode = TreeNode(root)  # 建立根节点
15         pos = inorder.index(root)  # 确定根节点在中序遍历中的索引位置
16 
17         preorderLeft = preorder[1:pos+1]  # 前序遍历的左子树
18         preorderRight = preorder[pos+1:]  # 前序遍历的右子树
19 
20         inorderLeft = inorder[:pos]  # 中序遍历的左子树
21         inorderRight = inorder[pos+1:]  # 中序遍历的右子树
22 
23         leftNode = self.buildTree(preorderLeft, inorderLeft)  # 递归到左子树的根节点
24         rightNode = self.buildTree(preorderRight, inorderRight)  # 递归到右子树的根节点
25         rootNode.left = leftNode
26         rootNode.right = rightNode
27         return rootNode

C++解法:

 1 struct TreeNode {
 2     int val;
 3     TreeNode *left;
 4     TreeNode *right;
 5     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 6 };
 7  
 8 class Solution {
 9 public:
10     TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
11         if (preorder.size() == 0 || inorder.size() == 0 || preorder.size() != inorder.size())  // 考虑异常情况
12             return NULL;
13 
14         int root = preorder[0];
15         TreeNode *rootNode = new TreeNode(root);  // 建立根节点时,一定要用new!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16         int pos;  // 根节点在中序遍历中的下标
17         for (int i = 0; i < inorder.size(); i++)
18             if (inorder[i] == root) {
19                 pos = i;
20                 break;
21             }
22 
23         vector<int> preorderLeft;  // 前序遍历的左子树
24         vector<int> preorderRight;  // 前序遍历的右子树
25         for (int i = 1; i <= pos; i++)
26             preorderLeft.push_back(preorder[i]);
27         for (int i = pos + 1; i < preorder.size(); i++)
28             preorderRight.push_back(preorder[i]);
29 
30         vector<int> inorderLeft;  // 中序遍历的左子树
31         vector<int> inorderRight;  // 中序遍历的右子树
32         for (int i = 0; i < pos; i++)
33             inorderLeft.push_back(inorder[i]);
34         for (int i = pos + 1; i < inorder.size(); i++)
35             inorderRight.push_back(inorder[i]);
36 
37         TreeNode *leftNode = buildTree(preorderLeft, inorderLeft);  // 递归到左子树的根节点
38         TreeNode *rightNode = buildTree(preorderRight, inorderRight);  // 递归到右子树的根节点
39         rootNode->left = leftNode;
40         rootNode->right = rightNode;
41 
42         return rootNode;
43     }
44 };
posted @ 2020-06-24 18:48  孔子?孟子?小柱子!  阅读(174)  评论(0编辑  收藏  举报