1. 程式人生 > >牛客網刷題--劍指offer(重建二叉樹)

牛客網刷題--劍指offer(重建二叉樹)

題目描述是這樣的:
給你一個樹的前序遍歷和中序遍歷,希望你能重建這個二叉樹的結構,題目還給了一個例子:某二叉樹的前序遍歷為{1, 2, 4, 7, 3, 5, 6, 8}和中序遍歷{4, 7, 2, 1, 5, 3, 8, 6},重建二叉樹並返回該二叉樹的根指標。
這裡,我們需要清楚,要想重建二叉樹,我們必須已知某二叉樹的中序遍歷序列,也就是說,只要知道前序,中序或這中序,後序遍歷序列都是可以重建出二叉樹的,但是若只知道前序和後序序列的二叉樹,我們是不能重建出二叉樹的。
那怎麼重建二叉樹呢?遞迴當然是最方便的了。因為前序遍歷,所以第一個結點是根結點,根結點找到之後,當然要在中序遍歷找了,而中序遍歷中的根結點左邊的所有結點就是該根結點的左子樹結點,該根結點右邊的所有結點是該根結點的右子樹。我們先處理左子樹,左子樹又是一個二叉樹,我們能從前邊的前序遍歷和中序遍歷中找到該二叉樹的所有結點,又組成了一個新的前序遍歷和中序遍歷序列,這樣重建這個新的二叉樹。左子樹處理完了之後在處理右子樹,完成遞迴操作。
遞迴的邏輯清楚了,那以什麼來結束遞迴操作呢?經過分析(所謂的分析就是自己動手在紙上劃,讓筆頭劃的指標像程式那樣跑起來,就能找到其中的結束條件),結束條件是指向前序序列的頭指標和尾指標指向同一元素且指向中序序列的頭指標和尾指標指向同一元素且前序序列指標指向的元素和中序序列指標指向的元素相同,那麼,就可以說,我遍歷完了所有的前序序列和中序序列,可以返回了。
那什麼時候重建二叉樹的左子樹呢?當然是當左子樹有結點了,同理,我們需要計算右子樹的結點數大於零,就要遞迴重建右子樹。
這次寫程式碼是非常的順利,經過上次兩個程式設計(奶牛問題和選鎮長問題),我的程式碼在本地上是能跑通的,可是到了牛客網的編譯器,就是執行時間過長,遞迴層數過深等問題,很打擊我的程式設計信心,但是這次,我在紙上寫了一邊,確定邏輯都沒有錯誤之後,就在牛客網提供的編譯器上敲,沒想到,一次就通過了。所以只要程式碼的邏輯正確,就大膽的提交執行吧。我的奶牛問題和選鎮長問題過一段時間在回過頭來看看吧,也許過一段時間,就能編譯通過。
現將重建二叉樹程式碼貼上如下,以供後面查閱:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    struct TreeNode * subTree(vector<int> pre, int preStart, int preEnd, vector
<int>
in, int inStart, int inEnd) { struct TreeNode * rootTree = (struct TreeNode *) malloc (sizeof(struct TreeNode)); rootTree -> val = pre[preStart]; rootTree -> left = NULL; rootTree -> right = NULL; if (preStart == preEnd && inStart == inEnd && pre[preStart] == in[inStart]) return
rootTree; int rootIndex = inStart; while (in[rootIndex] != pre[preStart]) rootIndex ++; int newLength = rootIndex - inStart; if (newLength > 0) rootTree -> left = subTree(pre, preStart + 1, preStart + newLength, in, inStart, rootIndex - 1); if (inEnd - rootIndex > 0) rootTree -> right = subTree(pre, preStart + newLength + 1, preEnd, in, rootIndex + 1, inEnd); return rootTree; } struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) { int preLength = pre.size(); int inLength = pre.size(); if (preLength == 0 || inLength == 0) return NULL; return subTree(pre, 0, preLength - 1, in, 0, inLength - 1); } };