1. 程式人生 > >Leetcode:222. Count Complete Tree Nodes

Leetcode:222. Count Complete Tree Nodes

題目:給定一顆完全二叉樹,就算共有多少節點

1.首次嘗試
拿到題目第一反應覺得很簡單啊,刷刷刷寫下如下程式碼:

class Solution {
public:
    int countNodes(TreeNode* root) {
        if(!root) return 0;
        if(!root->left && !root->right) return 1;
        return 1 + countNodes(root->left) + countNodes(root->right);
    }
};

一邊寫還想,就這破題目還hard難度,開玩笑吧。
結果一提交,發現超時。。。
然後仔細一想,發現沒有利用到完全二叉樹這個條件。上面程式碼可以計算任意二叉樹的節點數量,但是對於完全二叉樹這麼老老實實地計算就太慢了。

2.第二次嘗試
可以這樣:從根節點一直向左,計算左邊的高度;從根節點一直向右,計算右邊的高度。如果兩邊高度一樣,那麼說明完全二叉樹最下面一層也是滿的,用公式就算就行了。如果兩邊高度不一樣,即左邊比右邊高一,那麼關鍵就在於確定樹的最下面一層有多少葉子。
我的想法是這樣:用類似二分查詢的方法,確定最下面一層的分界點在哪。那麼對於一顆樹,如何找到從根到最下面一層位於中間的節點(如果最下面一層沒有,那就倒數第二層位於中間的節點)的高度呢?這樣:從根往左走一個,然後一直往右走,就可以了。
以上想法應該是可行的,但是程式碼實現起來太複雜,無奈作罷。

3.評論區答案

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        int lh = 0, rh = 0;
        auto ln = root;
        auto rn = root;
        while(ln) { ++lh; ln = ln->left; }
        while(rn) { ++rh; rn = rn->right; }
        if(lh == rh) return pow(2, lh)-1;
        return 1 + countNodes(root->left) + countNodes(root->right);
    }
};

核心要點就是一個:一棵完全二叉樹的兩棵子樹都是完全二叉樹。
計算兩邊的高度,如果兩邊高相等,那麼直接通過公式計算出來;如果不相等,那麼就遞迴計算左右子樹的節點數量再加一。
看到答案真的是要給跪了orz