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

【算法與數(shù)據(jù)結(jié)構(gòu)】236、LeetCode二叉樹(shù)的最近公共祖先

這篇具有很好參考價(jià)值的文章主要介紹了【算法與數(shù)據(jù)結(jié)構(gòu)】236、LeetCode二叉樹(shù)的最近公共祖先。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

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

一、題目

【算法與數(shù)據(jù)結(jié)構(gòu)】236、LeetCode二叉樹(shù)的最近公共祖先,算法,算法
【算法與數(shù)據(jù)結(jié)構(gòu)】236、LeetCode二叉樹(shù)的最近公共祖先,算法,算法

二、解法

??思路分析: 根據(jù)定義,最近祖先節(jié)點(diǎn)需要遍歷節(jié)點(diǎn)的左右子樹(shù),然后才能知道是否為最近祖先節(jié)點(diǎn)。那么這種需求是先遍歷左右節(jié)點(diǎn),然后遍歷中間節(jié)點(diǎn),屬于左右中的后序遍歷模式。因此在程序當(dāng)中,我們選擇遞歸中序遍歷。輸入?yún)?shù)為根節(jié)點(diǎn)p q節(jié)點(diǎn)。終止條件是當(dāng)前節(jié)點(diǎn)和p q當(dāng)中任意一個(gè)節(jié)點(diǎn)相等時(shí)就返回,遍歷到空節(jié)點(diǎn)也返回。因?yàn)槭呛笮虮闅v,根據(jù)遍歷完左右子樹(shù)后的返回值確定返回參數(shù),如果返回值都不為空,則當(dāng)前節(jié)點(diǎn)就是最近祖先節(jié)點(diǎn)。如果left為空,right不為空,則最近祖先節(jié)點(diǎn)在右子樹(shù),反之亦然。均為空則返回NULL
??程序如下

class Solution2 {
public:
    // 后序遍歷: 左右中
    // 1、輸入?yún)?shù)
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        // 2、終止條件
        if (root == q || root == p || root == NULL) return root;    // 如果節(jié)點(diǎn)相等或者是空節(jié)點(diǎn)返回

        // 3、單層遞歸邏輯
        TreeNode* left = lowestCommonAncestor(root->left, p, q);        // 左
        TreeNode* right = lowestCommonAncestor(root->right, p, q);      // 右

        // 1、返回值
        if (left != NULL && right != NULL) return root;
        if (left == NULL && right != NULL) return right;
        else if (left != NULL && right == NULL) return left;
        else { //  (left == NULL && right == NULL)
            return NULL;
        }
    }
};

??代碼優(yōu)化

class Solution {
public:
    // 后序遍歷: 左右中
    // 1、輸入?yún)?shù)
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        // 2、終止條件
        if (root == p || root == q || root == NULL) return root;    // 如果節(jié)點(diǎn)相等或者是空節(jié)點(diǎn)返回

        // 3、單層遞歸邏輯
        TreeNode* left = lowestCommonAncestor(root->left, p, q);        // 左
        TreeNode* right = lowestCommonAncestor(root->right, p, q);      // 右
        if (left != NULL && right != NULL) return root;
        if (left == NULL) return right;

        // 1、返回值
        return left;
    }
};

三、完整代碼

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

// 樹(shù)節(jié)點(diǎn)定義
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:
    // 后序遍歷: 左右中
    // 1、輸入?yún)?shù)
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        // 2、終止條件
        if (root == p || root == q || root == NULL) return root;    // 如果節(jié)點(diǎn)相等或者是空節(jié)點(diǎn)返回

        // 3、單層遞歸邏輯
        TreeNode* left = lowestCommonAncestor(root->left, p, q);        // 左
        TreeNode* right = lowestCommonAncestor(root->right, p, q);      // 右
        if (left != NULL && right != NULL) return root;
        if (left == NULL) return right;

        // 1、返回值
        return left;
    }
};

class Solution2 {
public:
    // 后序遍歷: 左右中
    // 1、輸入?yún)?shù)
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        // 2、終止條件
        if (root == q || root == p || root == NULL) return root;    // 如果節(jié)點(diǎn)相等或者是空節(jié)點(diǎn)返回

        // 3、單層遞歸邏輯
        TreeNode* left = lowestCommonAncestor(root->left, p, q);        // 左
        TreeNode* right = lowestCommonAncestor(root->right, p, q);      // 右

        // 1、返回值
        if (left != NULL && right != NULL) return root;
        if (left == NULL && right != NULL) return right;
        else if (left != NULL && right == NULL) return left;
        else { //  (left == NULL && right == NULL)
            return NULL;
        }
    }
};

// 前序遍歷迭代法創(chuàng)建二叉樹(shù),每次迭代將容器首元素彈出(彈出代碼還可以再優(yōu)化)
void Tree_Generator(vector<string>& t, TreeNode*& node) {
    if (!t.size() || t[0] == "NULL") return;    // 退出條件
    else {
        node = new TreeNode(stoi(t[0].c_str()));    // 中
        if (t.size()) {
            t.assign(t.begin() + 1, t.end());
            Tree_Generator(t, node->left);              // 左
        }
        if (t.size()) {
            t.assign(t.begin() + 1, t.end());
            Tree_Generator(t, node->right);             // 右
        }
    }
}

template<typename T>
void my_print(T& v, const string msg)
{
    cout << msg << endl;
    for (class T::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << ' ';
    }
    cout << endl;
}

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;
}

// 前序遍歷,找二叉樹(shù)中指定的鍵值
TreeNode* traversal_preOrder(TreeNode* cur, int val) {
    if (cur == NULL) return NULL;
    if (cur->val == val) return cur;        // 中
    if (traversal_preOrder(cur->left, val) != NULL) return traversal_preOrder(cur->left, val);        // 左   
    if (traversal_preOrder(cur->right, val) != NULL) return traversal_preOrder(cur->right, val);     // 右  
    return NULL;
}

int main()
{
    // 構(gòu)建二叉樹(shù)
    vector<string> t = { "3", "5", "6", "NULL", "NULL", "2", "7", "NULL", "NULL", "4", "NULL", "NULL", "1", "0", "NULL", "NULL", "8", "NULL", "NULL"};   // 前序遍歷
    my_print(t, "目標(biāo)樹(shù)");
    TreeNode* root = new TreeNode();
    Tree_Generator(t, root);
    vector<vector<int>> tree = levelOrder(root);
    my_print2<vector<vector<int>>, vector<int>>(tree, "目標(biāo)樹(shù):");

    // 構(gòu)建p, q節(jié)點(diǎn)
    int p = 5, q = 1;
    TreeNode* P_node = traversal_preOrder(root, p);
    TreeNode* Q_node = traversal_preOrder(root, q);

    // 找最近公共祖先節(jié)點(diǎn)
    Solution s;
    TreeNode* result = s.lowestCommonAncestor(root, P_node, Q_node);
    cout << "節(jié)點(diǎn) " << P_node->val << " 和節(jié)點(diǎn) " << Q_node->val << " 的最近公共祖先節(jié)點(diǎn)為 " << result->val << endl;

    system("pause");
    return 0;
}

end文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-707836.html

到了這里,關(guān)于【算法與數(shù)據(jù)結(jié)構(gòu)】236、LeetCode二叉樹(shù)的最近公共祖先的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)與算法之二叉樹(shù): Leetcode 98. 驗(yàn)證二叉搜索樹(shù) (Typescript版)

    驗(yàn)證二叉搜索樹(shù) https://leetcode.cn/problems/validate-binary-search-tree/ 描述 給你一個(gè)二叉樹(shù)的根節(jié)點(diǎn) root ,判斷其是否是一個(gè)有效的二叉搜索樹(shù) 有效 二叉搜索樹(shù)定義如下: 節(jié)點(diǎn)的左子樹(shù)只包含 小于 當(dāng)前節(jié)點(diǎn)的數(shù)。 節(jié)點(diǎn)的右子樹(shù)只包含 大于 當(dāng)前節(jié)點(diǎn)的數(shù)。 所有左子樹(shù)和右子樹(shù)自身

    2024年02月16日
    瀏覽(22)
  • 二叉樹(shù)(下)+Leetcode每日一題——“數(shù)據(jù)結(jié)構(gòu)與算法”“對(duì)稱(chēng)二叉樹(shù)”“另一棵樹(shù)的子樹(shù)”“二叉樹(shù)的前中后序遍歷”

    二叉樹(shù)(下)+Leetcode每日一題——“數(shù)據(jù)結(jié)構(gòu)與算法”“對(duì)稱(chēng)二叉樹(shù)”“另一棵樹(shù)的子樹(shù)”“二叉樹(shù)的前中后序遍歷”

    各位CSDN的uu們你們好呀,今天小雅蘭的內(nèi)容仍然是二叉樹(shù)和Leetcode每日一題,下面,就讓我們進(jìn)入二叉樹(shù)的世界吧!??! 這個(gè)題目需要重新定義一個(gè)函數(shù),函數(shù)參數(shù)需要有左子樹(shù)和右子樹(shù),題目所給定的函數(shù)無(wú)法解決問(wèn)題。 每個(gè)不為空的結(jié)點(diǎn),都可以認(rèn)為是一棵子樹(shù)的根?

    2024年02月16日
    瀏覽(29)
  • 二叉樹(shù)(中)+Leetcode每日一題——“數(shù)據(jù)結(jié)構(gòu)與算法”“劍指Offer55-I. 二叉樹(shù)的深度”“100.相同的樹(shù)”“965.單值二叉樹(shù)”

    二叉樹(shù)(中)+Leetcode每日一題——“數(shù)據(jù)結(jié)構(gòu)與算法”“劍指Offer55-I. 二叉樹(shù)的深度”“100.相同的樹(shù)”“965.單值二叉樹(shù)”

    各位CSDN的uu們你們好呀,今天繼續(xù)數(shù)據(jù)結(jié)構(gòu)與算法專(zhuān)欄中的二叉樹(shù),下面,讓我們進(jìn)入二叉樹(shù)的世界吧?。?! 二叉樹(shù)(上)——“數(shù)據(jù)結(jié)構(gòu)與算法”_認(rèn)真學(xué)習(xí)的小雅蘭.的博客-CSDN博客 二叉樹(shù)鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn) 二叉樹(shù)鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn) 求二叉樹(shù)的高度 但是這種寫(xiě)法有很大的問(wèn)題

    2024年02月17日
    瀏覽(32)
  • 【算法與數(shù)據(jù)結(jié)構(gòu)】106、LeetCode從中序與后序遍歷序列構(gòu)造二叉樹(shù)

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

    所有的LeetCode題解索引,可以看這篇文章——【算法和數(shù)據(jù)結(jié)構(gòu)】LeetCode題解。 ?? 思路分析 :首先我們要知道后序遍歷數(shù)組的最后一個(gè)元素必然是根節(jié)點(diǎn),然后根據(jù)根節(jié)點(diǎn)在中序遍歷數(shù)組中的位置進(jìn)行劃分,得到根節(jié)點(diǎn)的左右子樹(shù)遍歷數(shù)組,以此遞歸。當(dāng)然這里有一個(gè)前提

    2024年02月10日
    瀏覽(24)
  • 【LeetCode】【數(shù)據(jù)結(jié)構(gòu)】二叉樹(shù)必刷OJ題

    【LeetCode】【數(shù)據(jù)結(jié)構(gòu)】二叉樹(shù)必刷OJ題

    ?? 樊梓慕: 個(gè)人主頁(yè) ? ?? 個(gè)人專(zhuān)欄: 《C語(yǔ)言》《數(shù)據(jù)結(jié)構(gòu)》《藍(lán)橋杯試題》《LeetCode刷題筆記》《實(shí)訓(xùn)項(xiàng)目》 ?? 每一個(gè)不曾起舞的日子,都是對(duì)生命的辜負(fù) 目錄 前言 【LeetCode】226.翻轉(zhuǎn)二叉樹(shù) 【LeetCode】100.相同的樹(shù) 【LeetCode】5.對(duì)稱(chēng)二叉樹(shù) 【LeetCode】9.另一顆樹(shù)的子樹(shù)

    2024年02月08日
    瀏覽(22)
  • 【數(shù)據(jù)結(jié)構(gòu)和算法】--- 二叉樹(shù)(3)--二叉樹(shù)鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn)(1)

    【數(shù)據(jù)結(jié)構(gòu)和算法】--- 二叉樹(shù)(3)--二叉樹(shù)鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn)(1)

    在學(xué)習(xí)二叉樹(shù)的基本操作前,需先要?jiǎng)?chuàng)建一棵二叉樹(shù),然后才能學(xué)習(xí)其相關(guān)的基本操作。由于現(xiàn)在大家對(duì)二叉樹(shù)結(jié)構(gòu)掌握還不夠深入,且為了方便后面的介紹,此處手動(dòng)快速創(chuàng)建一棵簡(jiǎn)單的二叉樹(shù),快速進(jìn)入二叉樹(shù)操作學(xué)習(xí),等二叉樹(shù)結(jié)構(gòu)了解的差不多時(shí),我們反過(guò)頭再來(lái)研

    2024年01月25日
    瀏覽(28)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】—— 二叉樹(shù)

    【數(shù)據(jù)結(jié)構(gòu)與算法】—— 二叉樹(shù)

    目錄 一、樹(shù) 1、初識(shí)樹(shù) 2、樹(shù)的一些概念 3、樹(shù)的表示形式 二、二叉樹(shù) 1、初識(shí)二叉樹(shù) 2、兩種特殊的二叉樹(shù) 3、二叉樹(shù)的性質(zhì)? 4、二叉樹(shù)的遍歷 5、實(shí)現(xiàn)一棵二叉樹(shù)? 6、二叉樹(shù)題目(沒(méi)代碼的后面會(huì)給補(bǔ)上) (1)根節(jié)點(diǎn)沒(méi)有前驅(qū)。 (2)子樹(shù)的根節(jié)點(diǎn)只有一個(gè)前驅(qū),可以有

    2024年04月09日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu)與算法-二叉樹(shù)

    ????????在計(jì)算機(jī)科學(xué)中,數(shù)據(jù)結(jié)構(gòu)是組織和存儲(chǔ)數(shù)據(jù)的基礎(chǔ)框架,而算法則是處理這些數(shù)據(jù)的核心邏輯。在這眾多的數(shù)據(jù)結(jié)構(gòu)中,二叉樹(shù)因其獨(dú)特的層級(jí)結(jié)構(gòu)、高效的搜索和插入操作,成為廣泛應(yīng)用的一種非線(xiàn)性數(shù)據(jù)結(jié)構(gòu)。本文將深入探討二叉樹(shù)的定義、種類(lèi)、操作方法

    2024年03月10日
    瀏覽(43)
  • 二叉樹(shù)(上)——“數(shù)據(jù)結(jié)構(gòu)與算法”

    二叉樹(shù)(上)——“數(shù)據(jù)結(jié)構(gòu)與算法”

    各位CSDN的uu們好呀,好久沒(méi)有更新我的數(shù)據(jù)結(jié)構(gòu)與算法專(zhuān)欄啦,今天,小雅蘭繼續(xù)來(lái)更新二叉樹(shù)的內(nèi)容,下面,讓我們進(jìn)入鏈?zhǔn)蕉鏄?shù)的世界吧!?。?二叉樹(shù)鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn)? 二叉樹(shù)鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn) 普通的二叉樹(shù)的增刪查改是沒(méi)有價(jià)值的?。?! 只有搜索二叉樹(shù)的增刪查改才

    2024年02月15日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu)】樹(shù)與二叉樹(shù)(十三):遞歸復(fù)制二叉樹(shù)(算法CopyTree)

    【數(shù)據(jù)結(jié)構(gòu)】樹(shù)與二叉樹(shù)(十三):遞歸復(fù)制二叉樹(shù)(算法CopyTree)

    ??二叉樹(shù)是一種常見(jiàn)的樹(shù)狀數(shù)據(jù)結(jié)構(gòu),它由結(jié)點(diǎn)的有限集合組成。一個(gè)二叉樹(shù)要么是 空集 ,被稱(chēng)為 空二叉樹(shù) ,要么由一個(gè)根結(jié)點(diǎn)和兩棵不相交的子樹(shù)組成,分別稱(chēng)為 左子樹(shù) 和 右子樹(shù) 。每個(gè)結(jié)點(diǎn)最多有兩個(gè)子結(jié)點(diǎn),分別稱(chēng)為左子結(jié)點(diǎn)和右子結(jié)點(diǎn)。 引理5.1:二叉樹(shù)中層數(shù)

    2024年02月01日
    瀏覽(18)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包