LeetCode 每日一题笔记 日期:2026.06.06 题目:2196. 根据描述创建二叉树

LeetCode 每日一题笔记

0. 前言

  • 日期:2026.06.06
  • 题目:2196. 根据描述创建二叉树
  • 难度:中等
  • 标签:二叉树、哈希表、数组

1. 题目理解

问题描述

给定二维数组 descriptions,其中 descriptions[i] = [parent, child, isLeft],表示 parentchild 的父节点。

  • isLeft == 1,则 childparent 的左孩子;
  • isLeft == 0,则 childparent 的右孩子。
    根据描述构造完整二叉树,并返回根节点。

示例

输入:descriptions = [[20,15,1],[20,17,0],[50,20,1],[50,80,0],[80,19,1]]

输出:根节点为 50 的二叉树。

2. 解题思路

核心观察

  • 根节点的关键特征:没有父节点 (不会出现在任何 child 位置)。
  • 可以用数组/哈希表存储所有节点,一次性遍历即可构建完整树结构。

算法步骤

  1. 遍历 descriptions,创建父、子节点并建立左右关系;
  2. 用布尔数组标记所有有父节点的节点;
  3. 遍历节点,找到无父节点的节点作为根返回。

3. 代码实现

java 复制代码
package lc2196;
import java.util.HashSet;

class Solution {
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode() {
        }

        TreeNode(int val) {
            this.val = val;
        }

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    public TreeNode createBinaryTree(int[][] descriptions) {
        TreeNode root = new TreeNode(0);
        HashSet<Integer> father = new HashSet<Integer>();
        HashSet<Integer> kid = new HashSet<Integer>();
        int[][] arr = new int[100001][2];

        for (int i = 0; i < descriptions.length; i++) {
            //左孩子
            if (descriptions[i][2] == 1) {
                arr[descriptions[i][0]][0] = descriptions[i][1];
            }
            //右孩子
            else {
                arr[descriptions[i][0]][1] = descriptions[i][1];
            }
            kid.add(descriptions[i][1]);
        }

        for (int i = 0; i < descriptions.length; i++) {
            if (!kid.contains(descriptions[i][0])) {
                root.val = descriptions[i][0];
            }
        }

        method1(root, arr, arr[root.val][0], arr[root.val][1]);

        return root;
    }

    private void method1(TreeNode root, int[][] arr, int left, int right) {
        if (left != 0) {
            root.left = new TreeNode(left);
            method1(root.left, arr, arr[left][0], arr[left][1]);
        }

        if (right != 0) {
            root.right = new TreeNode(right);
            method1(root.right, arr, arr[right][0], arr[right][1]);
        }

    }
}

4. 代码优化说明

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
public TreeNode createBinaryTree(int[][] descriptions) {
    // 数组存储所有节点,下标对应节点值
    TreeNode[] nodes = new TreeNode[100001];
    // 标记节点是否存在父节点
    boolean[] existParent = new boolean[100001];

    for (int[] description : descriptions) {
        // 父节点不存在则创建
        if (nodes[description[0]] == null) {
            nodes[description[0]] = new TreeNode(description[0]);
        }
        // 子节点不存在则创建
        if (nodes[description[1]] == null) {
            nodes[description[1]] = new TreeNode(description[1]);
        }
        // 建立左右孩子关系
        if (description[2] == 1) {
            nodes[description[0]].left = nodes[description[1]];
        } else {
            nodes[description[0]].right = nodes[description[1]];
        }
        // 标记子节点已有父节点
        existParent[description[1]] = true;
    }

    // 遍历找到无父节点的根节点
    for (int i = 0; i < 100001; i++) {
        if (nodes[i] != null && !existParent[i]) {
            return nodes[i];
        }
    }
    return null;
}
}

5. 复杂度分析

  • 时间复杂度 :O(n)O(n)O(n),两次线性遍历(一次构建节点关系,一次找根节点)。
  • 空间复杂度 :O(n)O(n)O(n),主要为节点数组和标记数组的开销。

6. 总结

  • 核心思路:通过标记"无父节点"找到根节点,同时一次性构建树结构
  • 优化点:用数组直接存储节点,避免递归构建,减少分支判断,逻辑更简洁高效。
  • 关键技巧:根节点的识别方法是这类题的核心,利用"不会出现在子节点位置"这一特征快速定位。
相关推荐
ZhouDevin25 分钟前
算法论文/数据集3——CLD(TMLR2025)压缩训练集,仅保留对验证集有益的样本
人工智能·深度学习·算法·计算机视觉
Tim_1039 分钟前
【LeetCode】29、两数相除
算法·leetcode·职场和发展
船厂电气自动化ai大模型1 小时前
AI大模型与数学/第63课:矩阵定义、矩阵加法、标量乘法(逐级精讲)
数据结构·人工智能·深度学习·线性代数·算法
一条破秋裤1 小时前
STM32 学习笔记:PWM 驱动 LED 呼吸灯与舵机代码
笔记·stm32·学习
余额瞒着我当琳2 小时前
算法修炼 chapter 2 双指针进阶、盛最多水的容器、有效三角形的个数、两数之和、三数之和、四数之和
算法
你压到我腿毛了6662 小时前
C语言冒泡算法(Bubble sort)
c语言·数据结构·算法
靠沿3 小时前
贪心算法专题(三)
算法·贪心算法
super大力张3 小时前
MOE基于结构的药物设计(七):Ligand R-Vectors——如何判断配体可以从哪里继续生长?
数据库·算法·cadd·moe·svl·基于结构的药物设计
kyrie_sakura3 小时前
python学习笔记11 -- 进程和线程
笔记·python·学习
自小吃多3 小时前
PCB Editor软件差分对添加与设置笔记
笔记·嵌入式硬件