国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【算法與數(shù)據(jù)結(jié)構(gòu)】106、LeetCode從中序與后序遍歷序列構(gòu)造二叉樹

這篇具有很好參考價值的文章主要介紹了【算法與數(shù)據(jù)結(jié)構(gòu)】106、LeetCode從中序與后序遍歷序列構(gòu)造二叉樹。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

所有的LeetCode題解索引,可以看這篇文章——【算法和數(shù)據(jù)結(jié)構(gòu)】LeetCode題解。

一、題目

【算法與數(shù)據(jù)結(jié)構(gòu)】106、LeetCode從中序與后序遍歷序列構(gòu)造二叉樹,算法,算法

二、解法

??思路分析:首先我們要知道后序遍歷數(shù)組的最后一個元素必然是根節(jié)點,然后根據(jù)根節(jié)點在中序遍歷數(shù)組中的位置進行劃分,得到根節(jié)點的左右子樹遍歷數(shù)組,以此遞歸。當(dāng)然這里有一個前提,遍歷數(shù)組的元素不得重復(fù),否則構(gòu)造的二叉樹不唯一。因此我們根據(jù)根節(jié)點的值找到中序遍歷數(shù)組中的根節(jié)點索引,以此劃分出左右區(qū)間,然后進行遞歸。
??程序如下

class Solution {
public:
    TreeNode* traversal(const vector<int>& inorder, int inorderBegin, int inorderEnd, const vector<int>& postorder, int postorderBegin, int postorderEnd) { 
        // 1、判斷是否為空數(shù)組,直接返回
        if (inorderBegin == inorderEnd || postorderBegin == postorderEnd) return NULL;

        // 2、后序遍歷數(shù)組最后一個元素,就是當(dāng)前的中間節(jié)點
        int rootValue = postorder[postorderEnd - 1];    
        TreeNode* root = new TreeNode(rootValue);

        // 3、葉子節(jié)點,后序數(shù)組只剩下一個元素,樹構(gòu)造完畢,返回
        if (postorderBegin - postorderEnd == 1) return root;

        // 4、找切割點
        int delimiterIndex;
        for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {
            if (inorder[delimiterIndex] == rootValue) break; // 這里注意二叉樹遍歷數(shù)組的值不能重復(fù),否則二叉樹不唯一,這里默認是唯一二叉樹,值不重復(fù)。
        }

        // 5、切割中序數(shù)組,得到 中序左數(shù)組和中序右數(shù)組
        int leftinorderBegin = inorderBegin;
        int leftinorderEnd = delimiterIndex;

        int rightinorderBegin = delimiterIndex + 1;
        int rightinorderEnd = inorder.size();
       
        // 6、切割后序數(shù)組,得到 后序左數(shù)組和后序右數(shù)組
        int leftpostorderBegin = postorderBegin;
        int leftpostorderEnd = postorderBegin + delimiterIndex - inorderBegin;

        // 右后序區(qū)間,左閉右開[rightPostorderBegin, rightPostorderEnd)
        int rightPostorderBegin = postorderBegin + (delimiterIndex - inorderBegin);
        int rightPostorderEnd = postorderEnd - 1; // 排除最后一個元素,已經(jīng)作為節(jié)點了

        // 7、遞歸
        root->left = traversal(inorder, leftinorderBegin, leftinorderEnd, postorder, leftpostorderBegin, leftpostorderEnd);
        root->right = traversal(inorder, rightinorderBegin, rightinorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {       
        return traversal(inorder, 0, inorder.size(), postorder, 0, postorder.size());
    }
};

三、完整代碼

# include <iostream>
# include <vector>
# include <queue>
# include <string>
# include <algorithm>
# include <stack>
using namespace std;

// 樹節(jié)點定義
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    TreeNode* traversal(const vector<int>& inorder, int inorderBegin, int inorderEnd, const vector<int>& postorder, int postorderBegin, int postorderEnd) { 
        // 1、判斷是否為空數(shù)組,直接返回
        if (inorderBegin == inorderEnd || postorderBegin == postorderEnd) return NULL;

        // 2、后序遍歷數(shù)組最后一個元素,就是當(dāng)前的中間節(jié)點
        int rootValue = postorder[postorderEnd - 1];    
        TreeNode* root = new TreeNode(rootValue);

        // 3、葉子節(jié)點,后序數(shù)組只剩下一個元素,樹構(gòu)造完畢,返回
        if (postorderBegin - postorderEnd == 1) return root;

        // 4、找切割點
        int delimiterIndex;
        for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {
            if (inorder[delimiterIndex] == rootValue) break; // 這里注意二叉樹遍歷數(shù)組的值不能重復(fù),否則二叉樹不唯一,這里默認是唯一二叉樹,值不重復(fù)。
        }

        // 5、切割中序數(shù)組,得到 中序左數(shù)組和中序右數(shù)組
        int leftinorderBegin = inorderBegin;
        int leftinorderEnd = delimiterIndex;

        int rightinorderBegin = delimiterIndex + 1;
        int rightinorderEnd = inorder.size();
       
        // 6、切割后序數(shù)組,得到 后序左數(shù)組和后序右數(shù)組
        int leftpostorderBegin = postorderBegin;
        int leftpostorderEnd = postorderBegin + delimiterIndex - inorderBegin;

        // 右后序區(qū)間,左閉右開[rightPostorderBegin, rightPostorderEnd)
        int rightPostorderBegin = postorderBegin + (delimiterIndex - inorderBegin);
        int rightPostorderEnd = postorderEnd - 1; // 排除最后一個元素,已經(jīng)作為節(jié)點了

        // 7、遞歸
        root->left = traversal(inorder, leftinorderBegin, leftinorderEnd, postorder, leftpostorderBegin, leftpostorderEnd);
        root->right = traversal(inorder, rightinorderBegin, rightinorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {       
        return traversal(inorder, 0, inorder.size(), postorder, 0, postorder.size());
    }
};

template<class T1, class T2>
void my_print2(T1& v, const string str) {
    cout << str << endl;
    for (class T1::iterator vit = v.begin(); vit < v.end(); ++vit) {
        for (class T2::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {
            cout << *it << ' ';
        }
        cout << endl;
    }
}

// 層序遍歷
vector<vector<int>> levelOrder(TreeNode* root) {
    queue<TreeNode*> que;
    if (root != NULL) que.push(root);
    vector<vector<int>> result;
    while (!que.empty()) {
        int size = que.size();  // size必須固定, que.size()是不斷變化的
        vector<int> vec;
        for (int i = 0; i < size; ++i) {
            TreeNode* node = que.front();
            que.pop();
            vec.push_back(node->val);
            if (node->left) que.push(node->left);
            if (node->right) que.push(node->right);
        }
        result.push_back(vec);
    }
    return result;
}

int main()
{
    //vector<int> inorder = {9, 3, 15, 20, 7};
    //vector<int> postorder = { 9, 15, 7, 20, 3 };
    vector<int> inorder = { 1, 2, 3};
    vector<int> postorder = { 3, 2, 1};
    
    Solution s;
    TreeNode* root = s.buildTree(inorder, postorder);

    vector<vector<int>> tree = levelOrder(root);
    my_print2<vector<vector<int>>, vector<int>>(tree, "目標(biāo)樹:");

    system("pause");
    return 0;
}

end文章來源地址http://www.zghlxwxcb.cn/news/detail-685703.html

到了這里,關(guān)于【算法與數(shù)據(jù)結(jié)構(gòu)】106、LeetCode從中序與后序遍歷序列構(gòu)造二叉樹的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包