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

【算法與數(shù)據(jù)結(jié)構(gòu)】222、LeetCode完全二叉樹的節(jié)點個數(shù)

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

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

一、題目

【算法與數(shù)據(jù)結(jié)構(gòu)】222、LeetCode完全二叉樹的節(jié)點個數(shù),算法,算法

二、一般遍歷解法

??思路分析:利用層序遍歷,然后用num++記錄節(jié)點數(shù)量。其他的例如遞歸法和迭代法也是如此。
??層序遍歷程序如下

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        queue<TreeNode*> que;
        que.push(root);
        int num = 0;        // 節(jié)點數(shù)量
        while (!que.empty()) {
            int size = que.size();  // size必須固定, que.size()是不斷變化的
            for (int i = 0; i < size; ++i) {               
                TreeNode* node = que.front();
                que.pop();
                num++;
                if (node->left) que.push(node->left);   // 空節(jié)點不入隊
                if (node->right) que.push(node->right);
            }
        }
        return num;
    }
};

復雜度分析:

  • 時間復雜度: O ( n ) O(n) O(n)。
  • 空間復雜度: O ( n ) O(n) O(n)。
    ??遞歸程序如下(這應該是最精簡的版本了):
class Solution2 {
public:
    int countNodes(TreeNode* root) {
        return root == NULL ? 0 : countNodes(root->left) + countNodes(root->right) + 1;
    }
};

三、利用完全二叉樹性質(zhì)

??思路分析:完全二叉樹具有一個特性,假設它的深度為K,它的節(jié)點個數(shù)在 [ 2 K ? 1 ? 1 , 2 K ? 1 ] [2^{K-1}-1, 2^K-1] [2K?1?1,2K?1]之間,意味著它只有兩種情況,一種是滿二叉樹,一種是最后一層葉子節(jié)點沒有滿。對于情況一可以用 2 K ? 1 2^K-1 2K?1來計算,對于情況二分別遞歸其左子樹和右子樹,遞歸到一定深度一定有左子樹或者右子樹為滿二叉樹,然后按照情況一來計算。那么滿二叉樹的最左邊節(jié)點和最右邊節(jié)點的深度一定是相等的,依據(jù)這個特性判斷子樹是否為滿二叉樹。
【算法與數(shù)據(jù)結(jié)構(gòu)】222、LeetCode完全二叉樹的節(jié)點個數(shù),算法,算法
遞歸程序當中,我們要確定三個步驟,1、輸入?yún)?shù),返回值 2、遞歸終止條件 3、單層遞歸邏輯。輸入?yún)?shù)為中間節(jié)點,返回值為左子樹的節(jié)點數(shù)量+右子樹節(jié)點數(shù)量+1(+1是加上中間節(jié)點)。當節(jié)點為空時,遞歸終止,返回0。每次遞歸我們都要計算最左/右邊節(jié)點深度,然后判斷二者是否相等,如果相等則是滿二叉樹,返回 2 K ? 1 2^K-1 2K?1,K為深度。程序當中使用了左移運算符,因為運算符的優(yōu)先級問題,記得加括號。左移運算符是二進制運算,計算機計算的更快。
??程序如下

class Solution3 {
public:
    // 利用完全二叉樹的性質(zhì),遞歸法
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        TreeNode* left = root->left;
        TreeNode* right = root->right;
        int Ldepth = 0, Rdepth = 0;
        while (left) {      // 遞歸左子樹
            left = left->left;
            Ldepth++;
        }
        while (right) {     // 遞歸右子樹
            right = right->right;
            Rdepth++;
        }
        if (Ldepth == Rdepth) {
            return (2 << Ldepth) - 1;    // <<為左移運算符(位運算符),相當于2*leftDepth,但二進制運算計算機算的更快
        }
        return countNodes(root->left) + countNodes(root->right) + 1;
    }
};

復雜度分析:

  • 時間復雜度: O ( n ) O(n) O(n)。
  • 空間復雜度: O ( n ) O(n) O(n)。

四、完整代碼

# include <iostream>
# include <vector>
# include <queue>
# include <string>
# include <algorithm>
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:
    // 層序遍歷法
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        queue<TreeNode*> que;
        que.push(root);
        int num = 0;        // 節(jié)點數(shù)量
        while (!que.empty()) {
            int size = que.size();  // size必須固定, que.size()是不斷變化的
            for (int i = 0; i < size; ++i) {               
                TreeNode* node = que.front();
                que.pop();
                num++;
                if (node->left) que.push(node->left);   // 空節(jié)點不入隊
                if (node->right) que.push(node->right);
            }
        }
        return num;
    }
};

class Solution2 {
public:
    int countNodes(TreeNode* root) {
        return root == NULL ? 0 : countNodes(root->left) + countNodes(root->right) + 1;
    }
};

class Solution3 {
public:
    // 利用完全二叉樹的性質(zhì),遞歸法
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        TreeNode* left = root->left;
        TreeNode* right = root->right;
        int Ldepth = 0, Rdepth = 0;
        while (left) {      // 遞歸左子樹
            left = left->left;
            Ldepth++;
        }
        while (right) {     // 遞歸右子樹
            right = right->right;
            Rdepth++;
        }
        if (Ldepth == Rdepth) {
            return (2 << Ldepth) - 1;    // <<為左移運算符(位運算符),相當于2*leftDepth,但二進制運算計算機算的更快
        }
        return countNodes(root->left) + countNodes(root->right) + 1;
    }
};

void my_print(vector <string>& v, string msg)
{
    cout << msg << endl;
    for (vector<string>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << "  ";
    }
    cout << endl;
}

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

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

// 層序遍歷
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);   // 空節(jié)點不入隊
            if (node->right) que.push(node->right);
        }
        result.push_back(vec);
    }
    return result;
}

int main()
{
    vector<string> t = { "1", "2", "4", "NULL", "NULL", "5", "NULL", "NULL", "3", "6", "NULL", "NULL", "NULL"};   // 前序遍歷
    my_print(t, "目標樹");
    TreeNode* root = new TreeNode();
    Tree_Generator(t, root);
    vector<vector<int>> tree = levelOrder(root);
    my_print2(tree, "目標樹:");
    Solution2 s1;
    int result = s1.countNodes(root);
    cout << "節(jié)點數(shù)量為:" << result << endl;
    system("pause");
    return 0;
}

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

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

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

領支付寶紅包贊助服務器費用

相關(guān)文章

  • 【算法與數(shù)據(jù)結(jié)構(gòu)】226、LeetCode翻轉(zhuǎn)二叉樹

    【算法與數(shù)據(jù)結(jié)構(gòu)】226、LeetCode翻轉(zhuǎn)二叉樹

    所有的LeetCode題解索引,可以看這篇文章——【算法和數(shù)據(jù)結(jié)構(gòu)】LeetCode題解。 ?? 思路分析 :這道題的思路很簡單,本質(zhì)上就是遍歷每一個節(jié)點,然后交換左右節(jié)點。我們可以用前中后遍歷或者是層次遍歷法來做,參考這兩篇文章,【算法與數(shù)據(jù)結(jié)構(gòu)】144、94、145LeetCode二

    2024年02月16日
    瀏覽(18)
  • 【算法與數(shù)據(jù)結(jié)構(gòu)】98、LeetCode驗證二叉搜索樹

    【算法與數(shù)據(jù)結(jié)構(gòu)】98、LeetCode驗證二叉搜索樹

    所有的LeetCode題解索引,可以看這篇文章——【算法和數(shù)據(jù)結(jié)構(gòu)】LeetCode題解。 ?? 思路分析 :注意不要落入下面你的陷阱,筆者本來想左節(jié)點鍵值中間節(jié)點鍵值右節(jié)點鍵值即可,寫出如下代碼: ??在leetcode執(zhí)行時遇到下面的錯誤,再次讀題,發(fā)現(xiàn)是所有左子樹的鍵值小于

    2024年02月09日
    瀏覽(30)
  • 【算法與數(shù)據(jù)結(jié)構(gòu)】236、LeetCode二叉樹的最近公共祖先

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

    所有的LeetCode題解索引,可以看這篇文章——【算法和數(shù)據(jù)結(jié)構(gòu)】LeetCode題解。 ?? 思路分析 : 根據(jù)定義,最近祖先節(jié)點需要遍歷節(jié)點的左右子樹,然后才能知道是否為最近祖先節(jié)點。 那么這種需求是先遍歷左右節(jié)點,然后遍歷中間節(jié)點,屬于左右中的后序遍歷模式 。因此

    2024年02月09日
    瀏覽(27)
  • 【算法與數(shù)據(jù)結(jié)構(gòu)】700、LeetCode二叉搜索樹中的搜索

    【算法與數(shù)據(jù)結(jié)構(gòu)】700、LeetCode二叉搜索樹中的搜索

    所有的LeetCode題解索引,可以看這篇文章——【算法和數(shù)據(jù)結(jié)構(gòu)】LeetCode題解。 ?? 思路分析 :二叉搜索樹(Binary Search Tree, BST)的性質(zhì):所有左子樹節(jié)點鍵值 中間節(jié)點鍵值 所有右子樹節(jié)點鍵值,并且左右子樹都是二叉搜索樹。那么我們根據(jù)此性質(zhì),對比目標值和中間節(jié)點,如

    2024年02月10日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu)與算法之二叉樹: Leetcode 98. 驗證二叉搜索樹 (Typescript版)

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

    2024年02月16日
    瀏覽(22)
  • 數(shù)據(jù)結(jié)構(gòu)與算法之二叉樹: Leetcode 111. 二叉樹的最小深度 (Typescript版)

    二叉樹的最小深度 https://leetcode.cn/problems/minimum-depth-of-binary-tree/ 描述 就 給定一個二叉樹,找出其最小深度。 最小深度是從根節(jié)點到最近葉子節(jié)點的最短路徑上的節(jié)點數(shù)量。 說明:葉子節(jié)點是指沒有子節(jié)點的節(jié)點。 示例 1 示例 2 提示 樹中節(jié)點數(shù)的范圍在 [0, 1 0 5 10^5 1 0 5 ] 內(nèi)

    2024年02月06日
    瀏覽(29)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode96. 不同的二叉搜索樹

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode96. 不同的二叉搜索樹

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 很多人覺得動態(tài)規(guī)劃很難,但它就是固定套路而已。其實動態(tài)規(guī)劃只不過是將多余的步驟,提前放到dp數(shù)組中(就是一個數(shù)組,只

    2024年01月21日
    瀏覽(30)
  • 【算法與數(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ù)組的最后一個元素必然是根節(jié)點,然后根據(jù)根節(jié)點在中序遍歷數(shù)組中的位置進行劃分,得到根節(jié)點的左右子樹遍歷數(shù)組,以此遞歸。當然這里有一個前提

    2024年02月10日
    瀏覽(24)
  • 代碼隨想錄 Day13 二叉樹 LeetCode T104 二叉樹的最大深度 T111 二叉樹的最小深度 T222完全二叉樹的節(jié)點個數(shù)

    代碼隨想錄 Day13 二叉樹 LeetCode T104 二叉樹的最大深度 T111 二叉樹的最小深度 T222完全二叉樹的節(jié)點個數(shù)

    以下題解的更詳細思路來自于:代碼隨想錄 (programmercarl.com) 二叉樹的高度與深度 這里先補充一下二叉樹深度和高度的概念 高度:二叉樹中任意一個節(jié)點到葉子結(jié)點的距離 深度:二叉樹中任意一個節(jié)點到根節(jié)點的距離 下面給出一個圖便于理解 獲取高度與深度的遍歷方式 高度:后

    2024年02月08日
    瀏覽(29)
  • 數(shù)據(jù)結(jié)構(gòu):完全二叉樹(遞歸實現(xiàn))

    數(shù)據(jù)結(jié)構(gòu):完全二叉樹(遞歸實現(xiàn))

    ? ? ? ?如果完全二叉樹的深度為h,那么除了第h層外,其他層的節(jié)點個數(shù)都是滿的,第h層的節(jié)點都靠左排列。 ? ? ? ?完全二叉樹的編號方法是從上到下,從左到右,根節(jié)點為1號節(jié)點,設完全二叉樹的節(jié)點數(shù)為sum,某節(jié)點編號為i, ? ? ? ?當2*i = sum時,有左孩子,其編號為

    2024年01月24日
    瀏覽(27)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包