【劍指**】7.重建二叉樹

7.重建二叉樹

題目描述

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。

思路

思路和書上的一樣。
複述一下

將問題分解爲每次確定父節點,和左右子樹集合的問題。
第一個父節點即是根節點。

前序遍歷:根 左 右
中序遍歷:左 根 右

因此,在前序遍歷輸出的結果中,第一個值是 root 節點。

而在中序遍歷中, root 節點的左邊都是左子樹的節點。 root 節點的右邊都是右子樹的節點。於是,根據中序遍歷,可以得到左子樹和右子樹的節點個數。有了左右子樹的節點個數,就可以在前序遍歷中,也劃分出左右子樹的位置。

將上面的話總結一下:

  • 根據前序遍歷,獲得當前書的 父節點值;
  • 根據父節點值,在中序遍歷中,獲得左右節點個數的值;
  • 根據左右節點的個數,確定前序遍歷中,左右子樹的範圍;

用題目中的例子來說明思想:

已知:

前序: 1 2 4 7 3 5 6 8
中序: 4 7 2 1 5 3 8 6

第一步:
前序序列第一個值,是root = 1

第二步,找到中序序列中 值爲1的位置,獲得左右子樹:

(4 7 2) 1 (5 3 8 6)

可以看到,左子樹有3個節點。右子樹一共有 4 個節點。

第三步
於是,可以在前序序列中也進行劃分
1 (2 4 7) (3 5 6 8)

遞歸地,可知,根節點左子樹的父節點值是2. 右子樹的父節點值是3.

代碼

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if (pre.empty() || vin.empty() || pre.size() != vin.size()) return NULL;
        TreeNode* root = help(pre, vin, 0, pre.size()-1, 0, vin.size()-1);
        return root;
    }
    //pl = pre left; pr = pre right
    // vl = vin left; vr = vin right
    TreeNode* help(vector<int> pre, vector<int> vin, int pl, int pr, int vl, int vr) {
        TreeNode* node = new TreeNode(pre[pl]);
        if (pl == pr) {
            if (vl == vr && pre[pl] == vin[vl]) return node;
            else {
                cout<<"Error_01\n";
                return NULL;
            }
        }
        int middle = -1;
        // 根據當前節點,找到左右子樹的集合
        for (int i = vl; i <= vr; i++) {
            if (node->val == vin[i]) {
                middle = i;
                break;
            }
        }
        if (middle == -1) {
            cout<<"Error_02\n";
            return NULL;
        }
        node->left = help(pre, vin, pl+1, pl+middle-vl, vl, middle-1);
        node->right = help(pre, vin,pl+middle-vl+1, pr, middle+1, vr);
        return node;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章