輸入一棵二叉樹前序遍歷和中序遍歷的結果,請重建該二叉樹。c++
注意:數組
樣例數據結構
給定: 前序遍歷是:[3, 9, 20, 15, 7] 中序遍歷是:[9, 3, 15, 20, 7] 返回:[3, 9, 20, null, null, 15, 7, null, null, null, null] 返回的二叉樹以下所示: 3 / \ 9 20 / \ 15 7
這是題目地址,有興趣的能夠作一下。ui
這個是本身作的,準確來講算是實踐了一下本身上數據結構課學到的知識吧。code
若是前序序列不爲空,那麼第一個數必定是樹的根。咱們再從中序序列找到這個數所在的位置,左半部分就是根的左子樹,右半部分就是根的右子樹,咱們能夠把左子樹再看成一棵樹,適當縮小先序序列的範圍,第一個數就是這個左子樹的根,而後再在中序序列去尋找這個數,繼續劃分,依此類推,當序列只剩下一個數時,表明咱們找到了葉子節點,就不須要再繼續劃分了。遞歸
道理很簡單,可是操做起來出了點問題,仍是邊界問題,要親自實現一遍才知道本身哪裏有問題。get
本身的代碼也蠻複雜的,沒有用一些數記錄下標,直接將序列縮小進行遞歸,若是是利用下標值,能夠不須要這麼複雜。(此處就不修改代碼了)io
struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; void insertToTree(TreeNode* T, vector<int> preorder, vector<int> inorder) { T->val = preorder[0]; //當此時數組中只有一個數時,表示當前節點無左右孩子,爲樹葉 if (inorder.size() == 1) return; int i = 0; //尋找該數在中序數組中的位置,左半部分爲其左子樹,右半部分爲其右子樹。 for (; i < inorder.size(); i++) { if (inorder[i] == T->val) break; } //此時位於中序數組第一位,代表無左孩子 if (i == 0) { T->left = NULL; T->right = new TreeNode(0); insertToTree(T->right, vector<int>(preorder.begin() + i + 1, preorder.end()), vector<int>(inorder.begin() + i + 1, inorder.end())); } //位於中序數組最後一位,代表無右孩子 else if (i == inorder.size() - 1) { T->right = NULL; T->left = new TreeNode(0); insertToTree(T->left, vector<int>(preorder.begin() + 1, preorder.begin() + i + 1), vector<int>(inorder.begin(), inorder.begin() + i)); } //有左右孩子 else { T->right = new TreeNode(0); T->left = new TreeNode(0); insertToTree(T->left, vector<int>(preorder.begin() + 1, preorder.begin() + i + 1), vector<int>(inorder.begin(), inorder.begin() + i)); insertToTree(T->right, vector<int>(preorder.begin() + i + 1, preorder.end()), vector<int>(inorder.begin() + i + 1, inorder.end())); } } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { //若是是空序列,返回空樹 if (inorder.size() == 0) return NULL; TreeNode* T = new TreeNode(0); insertToTree(T, preorder, inorder); return T; }
這是題解,仍是學的知識沒用上,忘記了散列表這麼好用的東西。class
大佬的題解的原地址二叉樹
思路和我本身想的是基本同樣的,只不過大佬在中序序列找數的這個過程當中用的是散列表(學了一直沒用過,致使如今都不會用)
unordered_map<int,int> pos; TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { int n = preorder.size(); for (int i = 0; i < n; i ++ ) pos[inorder[i]] = i; return dfs(preorder, inorder, 0, n - 1, 0, n - 1); } TreeNode* dfs(vector<int>&pre, vector<int>&in, int pl, int pr, int il, int ir) { if (pl > pr) return NULL; int k = pos[pre[pl]] - il; TreeNode* root = new TreeNode(pre[pl]); root->left = dfs(pre, in, pl + 1, pl + k, il, il + k - 1); root->right = dfs(pre, in, pl + k + 1, pr, il + k + 1, ir); return root; } 做者:yxc 連接:https://www.acwing.com/solution/content/706/ 來源:AcWing 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。