leetcode
leetcode 651 ~ 700
将 N 叉树编码为二叉树

将 N 叉树编码为二叉树

难度:

标签:

题目描述

代码结果

运行时间: 46 ms, 内存: 17.4 MB


/*
 * 思路:
 * 使用 Java Stream 编码 N 叉树为二叉树和解码二叉树为 N 叉树。
 * 
 * 主要步骤与非 Stream 版本相同,但我们将使用 Stream API 来处理孩子节点的编码和解码。
 */

import java.util.*;
import java.util.stream.*;

class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int val) {
        this.val = val;
    }

    public Node(int val, List<Node> children) {
        this.val = val;
        this.children = children;
    }
}

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

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

public class Codec {
    public TreeNode encode(Node root) {
        if (root == null) return null;

        TreeNode newRoot = new TreeNode(root.val);
        if (!root.children.isEmpty()) {
            newRoot.left = encode(root.children.get(0));
        }

        TreeNode current = newRoot.left;
        root.children.stream().skip(1).forEach(child -> {
            current.right = encode(child);
            current = current.right;
        });

        return newRoot;
    }

    public Node decode(TreeNode root) {
        if (root == null) return null;

        Node newRoot = new Node(root.val, new ArrayList<>());
        TreeNode current = root.left;

        Stream.iterate(current, Objects::nonNull, node -> node.right)
              .forEach(node -> newRoot.children.add(decode(node)));

        return newRoot;
    }
}

解释

方法:

这个题解通过将N叉树(N-ary Tree)编码为二叉树(Binary Tree)的方式解决了如何在二叉树的数据结构中表示一个N叉树的问题。编码过程中,每个N叉树节点的所有子节点被转换为二叉树中的左子树,其中每个子节点成为前一个子节点的右子节点。解码过程则是编码的逆过程,它通过遍历二叉树,重新构建出原始的N叉树结构。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在编码过程中选择将N叉树的第一个子节点作为二叉树左子节点,而将其余子节点递归为右子节点?
在编码N叉树到二叉树的过程中,选择第一个子节点作为二叉树的左子节点是为了保持子节点的顺序和层次结构。将第一个子节点作为左子节点后,可以利用二叉树的右子节点表示N叉树中同一父节点的其余子节点。这种方法使得每一个N叉树节点的子节点列表可以通过二叉树的左子节点和右子节点链式地表示出来,从而实现N叉树到二叉树的转换。
🦆
在解码过程中,如何确保原始N叉树的子节点顺序被正确恢复?
在解码过程中,通过递归地访问二叉树的左子节点来恢复N叉树节点的子节点,并通过右子节点递归地恢复同一父节点下的其他子节点。这种顺序访问确保了原始N叉树中子节点的顺序被完整地保持。首先解码作为左子节点的第一个子节点,然后递归地解码右子节点链中的其他节点,这样可以确保所有子节点按照原始的顺序和层级关系被正确恢复。
🦆
在`encode_children`方法中,对于递归编码`children[1:]`的方式,这种切片操作的空间复杂度是多少?是否会影响算法的整体性能?
在`encode_children`方法中,使用`children[1:]`进行切片操作,这会创建当前子节点列表的一个新副本,除了第一个元素外包含所有子节点。这种切片操作的空间复杂度为O(n),其中n是子节点的数量,因为它需要额外的空间来存储副本。虽然这增加了空间复杂度,但通常不会对算法的整体性能产生显著影响,除非子节点的数量非常大。在实际应用中,可以通过优化代码结构,比如使用迭代器或索引,来减少不必要的空间使用,提高性能。

相关问题

序列化和反序列化 N 叉树

序列化和反序列化 N 叉树