以下写法中,height是从叶节点往上的节点数,空节点为0、叶节点为1;depth与height不区分。 都不像教科书上的,height定义为离叶节点的边数,叶节点高度为0;depth定义为离根节点的边数,根节点深度为0。

满二叉树的节点数

int countNodes(TreeNode* root) {
    if (!root) return 0;
    int leftH = getHeight(root->left);
    int rightH = getHeight(root->right);
    if (leftH == rightH) { // 左子树是满二叉树,左子树和根节点共(2^leftH-1)+1
        return (1 << leftH) + countNodes(root->right);
    } else { // 右子树是满二叉树
        return (1 << rightH) + countNodes(root->left);
    }
}

int getHeight(TreeNode *root) {
    int height = 0;
    while (root) {
        height++;
        root = root->left;
    }
    return height;
}

把叶节点一遍遍剥离

先剥离高度为0的节点,再剥离高度为1的节点……

vector<vector<int>> findLeaves(TreeNode* root) {
    vector<vector<int>> ans;
    getHeight(root, ans);
    return ans;
}

int getHeight(TreeNode *root, vector<vector<int>> &ans) {
    // 高h节点放到ans[h]中,让叶节点高为0,故定义空节点高为-1
    if (!root) return -1;
    auto left = getHeight(root->left, ans);
    auto right = getHeight(root->right, ans);
    int h = 1 + max(left, right);
    
    if (h == ans.size()) ans.push_back({});
    ans[h].push_back(root->val);
    return h;
}

无向图的哪些节点提作树中心,可使树高度最小

vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
    // 叶节点到这些“根”的距离最长,从外往内一圈圈删除叶节点,最后剩下的可作为根。
    // bfs不断删除度为1的叶节点,根据最长路径的奇偶性,可能剩下1个或2个节点。
    vector<vector<int>> adj(n);
    for (auto &edge : edges) {
        adj[edge[0]].push_back(edge[1]);
        adj[edge[1]].push_back(edge[0]);
    }
    vector<int> leaves;
    vector<int> degree(n);
    for (int i = 0; i < n; i++) {
        degree[i] = adj[i].size();
        if (degree[i] == 0 || degree[i] == 1) { // 单个节点的度为0
            leaves.push_back(i);
            degree[i] = 0; // 删除叶节点
        }
    }
    
    int count = leaves.size();
    while (count < n) {
        vector<int> newLeaves;
        for (int u : leaves) {
            for (int v : adj[u]) {
                if (--degree[v] == 1) newLeaves.push_back(v);
            }
            degree[u] = 0; // 删除叶节点
        }
        swap(leaves, newLeaves);
        count += leaves.size();
    }
    return leaves;
}