子树完全二叉树的判断

https://leetcode.cn/problems/k-th-largest-perfect-subtree-size-in-binary-tree/description/

  1. 第 K 大的完美二叉子树的大小

提示
给你一棵 二叉树 的根节点 root 和一个整数k。
返回第 k 大的 完美二叉子树 的大小,如果不存在则返回 -1。
完美二叉树 是指所有叶子节点都在同一层级的树,且每个父节点恰有两个子节点。

示例 1:
输入: root = [5,3,6,5,2,5,7,1,8,null,null,6,8], k = 2
输出: 3
解释:
完美二叉子树的根节点在图中以黑色突出显示。它们的大小按非递增顺序排列为 [3, 3, 1, 1, 1, 1, 1, 1]。
第 2 大的完美二叉子树的大小是 3。

示例 2:
输入: root = [1,2,3,4,5,6,7], k = 1
输出: 7
解释:
完美二叉子树的大小按非递增顺序排列为 [7, 3, 3, 1, 1, 1, 1]。最大的完美二叉子树的大小是 7。

示例 3:
输入: root = [1,2,3,null,4], k = 3
输出: -1
解释:
完美二叉子树的大小按非递增顺序排列为 [1, 1]。完美二叉子树的数量少于 3。

提示:
树中的节点数目在 [1, 2000] 范围内。
1 <= Node.val <= 2000
1 <= k <= 1024

/**
 * Definition for a binary tree node.
 * 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:
    vector<int>ans;
    int dfs(TreeNode* root){
        if(!root){
            return 0;
        }
        int l=dfs(root->left),r=dfs(root->right);
        if(l==r&&l!=-1){
            ans.push_back(l+r+1);
            return l+r+1;
        }
        return -1;
        
    }
    int kthLargestPerfectSubtree(TreeNode* root, int k) {
        dfs(root);
        sort(ans.begin(),ans.end(),[&](int a,int b){
            return a>b;
        });
        if(k>=ans.size()){
            return -1;
        }
        else{
            return ans[k-1];
        }
    }
};

这个题目还是比较简单的。因为它是那种左右建图

下面是用vector建图怎么判断完全二叉树

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

const int maxn = 1e5 + 100;
vector<int> e[maxn];  // 邻接表存储图
int vis[maxn];        // 存储每个节点的子树是否为完全二叉树

// 返回当前子树的节点数,并判断该子树是否为完全二叉树
int dfs(int u, int fa) {
    int child_count = 0;  // 子节点计数
    
    for (int v : e[u]) {
        if (v != fa) {
            child_count += dfs(v, u);  // 递归计算子节点总数
        }
    }
    
    // 根据子节点个数判断该节点是否为完全二叉树
    vis[u] = (child_count == 0 || child_count == 2);  // 没有或正好两个子节点
    return 1 + child_count;  // 返回包括自身的节点数
}

int main() {
    int n, m, l, r;
    cin >> n >> m;
    
    for (int i = 1; i <= m; i++) {
        cin >> l >> r;
        e[l].push_back(r);
        e[r].push_back(l);
    }
    
    dfs(1, -1);  // 从节点1开始遍历
    
    for (int i = 1; i <= n; i++) {
        cout << vis[i] << " ";  // 输出每个节点是否为完全二叉树的根
    }
    
    return 0;
}

posted @ 2024-10-17 17:14  lipu123  阅读(29)  评论(0)    收藏  举报