You need to enable JavaScript to run this app. Java练习:如何从树节点数组中删除指定值为根的对应子树
优惠活动
大模型
产品
解决方案
定价
更多

Java练习:如何从树节点数组中删除指定值为根的对应子树

问题解答

思路正确性确认

你的思路完全可行,用临时集合筛选需要保留的节点最后再转回数组的方案,避开了原地修改数组的复杂度,逻辑清晰且不易出错。

具体实现步骤

你只需要先完成「收集所有待删除节点ID」的前置步骤,再过滤原数组即可,核心逻辑如下:

  • 首先确认节点结构(题目已提供可直接跳过)
class TreeNode {
    // 节点自身唯一ID
    int id;
    // 父节点ID,根节点的parentId通常约定为-1或0,以题目规则为准
    int parentId;
    // 题目给定的节点值
    int value;
    // 构造方法、getter/setter省略
}
  • 实现删除逻辑,推荐用HashSet存储待删除ID,查询时间复杂度为O(1),结合BFS遍历所有后代节点:
public TreeNode[] deleteSubtree(TreeNode[] nodes, int targetValue) {
    Set<Integer> toDeleteIds = new HashSet<>();
    Queue<Integer> queue = new LinkedList<>();

    // 第一步:找到待删除的子树根节点
    for (TreeNode node : nodes) {
        if (node.value == targetValue) {
            toDeleteIds.add(node.id);
            queue.add(node.id);
            // 如果题目允许节点值重复,删除本行break即可
            break;
        }
    }

    // 第二步:BFS遍历所有后代,加入待删除集合
    while (!queue.isEmpty()) {
        Integer currentParentId = queue.poll();
        for (TreeNode node : nodes) {
            if (node.parentId == currentParentId && !toDeleteIds.contains(node.id)) {
                toDeleteIds.add(node.id);
                queue.add(node.id);
            }
        }
    }

    // 第三步:过滤保留节点,转数组返回
    List<TreeNode> retainNodes = new ArrayList<>();
    for (TreeNode node : nodes) {
        if (!toDeleteIds.contains(node.id)) {
            retainNodes.add(node);
        }
    }
    return retainNodes.toArray(new TreeNode[0]);
}

逻辑说明

后代节点的判定逻辑非常直接:子节点的parentId一定等于它直接父节点的id,只要父节点在待删除集合中,对应的子节点也属于待删除范围,通过BFS就能逐层把所有子孙后代全部识别出来。
如果处理的节点量级很大,可以提前遍历一次数组构建Map<Integer, List<TreeNode>> parentIdToChildren的映射,把相同parentId的节点提前归类,查找子节点时不需要每次遍历全数组,效率更高。
如果不存在值等于targetValue的节点,待删除集合为空,方法会直接返回原数组所有元素,符合预期。


内容的提问来源于stack exchange,提问作者Hboss62

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 20:51:02