1. 程式人生 > >【劍指offer】面試題7:重建二叉樹【C++版本】

【劍指offer】面試題7:重建二叉樹【C++版本】

題目:

重建二叉樹

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹(假設沒有重複數字)。樹節點定義如下:

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}
};

解題思路:

1.前序遍歷的第一個數字總是樹的根節點的值。但在中序遍歷中,根節點的值在序列的中間,其中左子樹的節點的值位於根節點的值的左邊,右子樹的節點的值位於根節點的值的右邊。要掃描中序遍歷序列,才能找到根節點的值。


2.又因為前序遍歷總是在根節點後先遍歷完左子樹,才會遍歷右子樹,所以由後續遍歷推斷出左子樹中節點的數目之後,前序遍歷中根節點之後的相同數目的值都是左子樹的節點的值。剩下的就是右子樹的值。這樣就分別找到了左右子樹序列。
3.分別確定了根節點和左右子樹的前序、中序遍歷,我們可以用同樣的方法構建左右子樹,剩下的可以用遞迴來完成。

可以AC的解法【C++版本】

#include <vector>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <algorithm>
using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) :val(x), left(nullptr), right(nullptr) {} }; TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin); int main() { vector<int> pre{1,2,4,5,3,6,7}; vector
<int>
vin{4,2,5,1,6,3,7}; TreeNode *newRoot = reConstructBinaryTree(pre, vin); system("pause"); return 0; } TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) { if (pre.size() == 0 || pre.size() != vin.size()) return nullptr; int root = pre[0]; TreeNode *newNode = new TreeNode(root); //如果只剩一個節點了,那麼可以直接返回 if (pre.size() == 1) return newNode; auto posi = find(vin.begin(), vin.end(), root); //錯誤檢測 if (posi == vin.end()) { return nullptr; } int leftSize = posi - vin.begin(); int rightSize = vin.end() - posi - 1; //遞迴求解 //這裡取前序和後序遍歷的左右子樹可能有點繞,可以好好思考一下 newNode->left = reConstructBinaryTree(vector<int>(pre.begin() + 1, pre.begin() + 1 + leftSize), vector<int>(vin.begin(), vin.begin() + leftSize)); newNode->right = reConstructBinaryTree(vector<int>(pre.begin() + 1 + leftSize, pre.end()), vector<int>(vin.begin() + leftSize + 1, vin.end())); return newNode; }