leetcode
leetcode 1401 ~ 1450
N 叉树的直径

N 叉树的直径

难度:

标签:

题目描述

代码结果

运行时间: 38 ms, 内存: 0.0 MB


/*
 * Leetcode 1522: Diameter of N-ary Tree (Java Stream)
 * 
 * Problem Statement: Given an N-ary tree, find the length of the diameter. 
 * The diameter of an N-ary tree is the longest path between any two nodes, 
 * which may or may not pass through the root.
 * 
 * Approach:
 * 1. Use a helper function to determine the depth of the tree recursively.
 * 2. For each node, use streams to calculate the depths of its children.
 * 3. Track the two largest depths to compute the diameter.
 * 4. Return the maximum diameter found.
 */

import java.util.Comparator;
import java.util.List;

class Solution {
    private int maxDiameter = 0;
    
    public int diameter(Node root) {
        if (root == null) return 0;
        depth(root);
        return maxDiameter;
    }
    
    private int depth(Node node) {
        if (node == null) return 0;
        List<Integer> depths = node.children.stream().map(this::depth).sorted(Comparator.reverseOrder()).toList();
        int max1 = depths.size() > 0 ? depths.get(0) : 0;
        int max2 = depths.size() > 1 ? depths.get(1) : 0;
        maxDiameter = Math.max(maxDiameter, max1 + max2);
        return max1 + 1;
    }
}

解释

方法:

该题解通过递归的方式计算N叉树的直径。递归函数`heights`计算并返回从当前节点到其最远叶子节点的最大高度。同时,该函数维护一个全局变量`ans`用来记录遍历过程中遇到的最大直径。对于每个节点,我们考虑通过该节点的两条最长路径(可能的直径),这是通过维护两个最大高度`toph1`和`toph2`实现的。每次访问子节点时,更新这两个最大高度,如果当前节点的高度大于`toph1`,则更新`toph1`和`toph2`;如果只大于`toph2`,则只更新`toph2`。最后,`toph1`和`toph2`的和可能会更新全局最大直径`ans`。

时间复杂度:

O(N)

空间复杂度:

O(N)

代码细节讲解

🦆
在递归函数`heights`中,为什么要同时维护两个最大高度`toph1`和`toph2`?
在N叉树中,节点的直径可能是通过该节点连接其两个最长子树的路径的长度。因此,为了计算通过当前节点的可能直径,我们需要知道从该节点出发的两个最长路径(子树高度)。`toph1`和`toph2`分别维护这两个最大高度,使我们能够在每个节点处计算通过该节点的最长路径,即可能的直径。
🦆
你是如何确保`toph1`和`toph2`总是记录当前节点的两个最长子路径的高度?
在递归过程中,对每个子节点计算其高度后,我们会比较这个高度与当前的`toph1`和`toph2`。如果当前子节点的高度超过`toph1`,则说明我们找到了一个新的最长路径,将`toph1`更新为这个新的最长路径,原`toph1`变为`toph2`。如果子节点的高度没有超过`toph1`但超过了`toph2`,则只更新`toph2`。这样保证了`toph1`和`toph2`始终是当前节点两个最长子路径的高度。
🦆
全局变量`ans`的最大值是如何通过`toph1 + toph2`更新的,能否解释这种更新方式背后的逻辑?
在每个节点,通过该节点的直径可以视为其两个最长子树的高度之和。因此,在更新`toph1`和`toph2`后,我们通过计算`toph1 + toph2`来获取通过当前节点的最大直径,并与全局变量`ans`进行比较。如果`toph1 + toph2`的值大于现有的`ans`,则更新`ans`。这种方法确保了无论直径穿过树的哪个部分,都能够捕获并更新最大直径。
🦆
在递归函数中,返回值`max(toph1, toph2) + 1`的计算方式是否意味着我们总是选择经过较高子树的路径作为当前节点的高度?
是的,返回值`max(toph1, toph2) + 1`确实表示我们选择经过较高子树的路径作为当前节点的高度。这是因为树中每个节点的高度定义为从该节点到其最远叶子节点的路径长度。因此,从当前节点出发的最高路径决定了该节点的高度。`max(toph1, toph2)`选出两个最长子路径中的较长者,`+1`表示加上当前节点到该子节点的一步距离。

相关问题