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. 总结

  • 核心思路:通过标记"无父节点"找到根节点,同时一次性构建树结构
  • 优化点:用数组直接存储节点,避免递归构建,减少分支判断,逻辑更简洁高效。
  • 关键技巧:根节点的识别方法是这类题的核心,利用"不会出现在子节点位置"这一特征快速定位。
相关推荐
想做小南娘,发现自己是女生喵37 分钟前
第 2 章 顺序表和 vector
java·数据结构·算法
艾醒1 小时前
2026年第29周(7.13-7.19)AI全复盘:技术突破、行业趣闻翻车、算力服务器商业动态
人工智能·算法
雪碧聊技术2 小时前
动态规划算法—01背包问题
算法·动态规划
bu_shuo2 小时前
c与cpp中的argc和argv
c语言·c++·算法
普贤莲花2 小时前
【2026年第29周---写于20260718】---整理,断舍离
程序人生·算法·生活
Reart2 小时前
Leetcode 674.最长连续递增序列 (719)
后端·算法
Reart2 小时前
Leetcode 300.最长递增子序列(719)
算法
可编程芯片开发2 小时前
VSG虚拟同步发电机simulink建模与仿真
算法
en.en..2 小时前
冒泡排序与选择排序完整对比解析
开发语言·数据结构·算法·c#·排序算法
兰令水3 小时前
hot100【acm版】【2026.7.18打卡-java版本】
java·开发语言·算法