【问题标题】:I cannot set the root of the tree to null?我不能将树的根设置为空?
【发布时间】:2020-09-17 04:28:59
【问题描述】:

我试图在 leetcode 上解决这个问题,通过查看我所写的内容,我认为我的逻辑是正确的,但我得到了相同的树作为输出,这是错误的。我有一个疑问,我可以不将树根的当前范围设置为 null 吗?在看到人们的解决方案后,他们使 root.left null 或 root.right null 不像我的根本身。 我是否在这里遗漏了一些基本概念。
链接到 LeetCode 问题:- https://leetcode.com/problems/binary-tree-pruning/
我的解决方案:-

/**
 * 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 pruneTree(TreeNode root) {
        cleanTree(root);
        return root;
    }
    
    public boolean cleanTree(TreeNode root) {
        if(root == null) {
            return true;
        }
        boolean left = cleanTree(root.left);
        boolean right = cleanTree(root.right);
        if(root.val == 0 && left  && right) {
            root = null;
            return true;
        }
        
        return false;
    }
}

【问题讨论】:

  • “我有一个疑问,我不能将树的根设置为空” 既然没有要求您这样做,那为什么要担心呢?任务是“返回同一棵树,其中每个 subtree (给定树的)不包含 1 已被删除”。由于您只是删除子树,因此 根节点将始终保留
  • 您将cleanTree() 参数命名为root 的事实令人困惑,因为大多数时候,该值不是树的根。 pruneTree() 的参数是“树的根”。 cleanTree() 的参数只是一些节点。 --- 你永远不应该将节点本身清空,你将 leftright 引用清空,然后返回 true 如果你希望 caller 清空对节点的引用.
  • 所以你在问为什么root = null 不会在调用者中取消root.leftroot.right。答案在这里:Is Java “pass-by-reference” or “pass-by-value”?.
  • @Andreas 谢谢你,现在我清楚地知道我错在哪里了。你完全清除了我对事情如何传递的怀疑

标签: java data-structures tree


【解决方案1】:

他们将root.leftroot.right 设置为null,因为他们无法将当前节点root 设置为null。

像在 if 语句中所做的那样将root 设置为 null 只会在当前方法的范围内将 root 的内存地址设置为 null。 pruneTree 方法不会看到 root 变为 null。

旁注,不保证根节点不为空。 例如与树

 0 <--root
0 0

,根为空

【讨论】:

  • 因为分配是“返回同一棵树,其中每个 subtree (给定树的)不包含 1 已被删除”。只有子树被清空,根始终保留并且永远不会设置为空。答案的后半部分是错误的。
  • 这个问题肯定含糊不清,但我昨天编写了这个确切的问题,假设全零树的根为空,并且它适用于每个测试用例,更不用说解决方案了lc 网站做了和我一样的事情
【解决方案2】:

问题是在java中传递给方法的变量永远不会被方法本身分配。 这是为了防止恶意调用意外修改传递的变量而引入的。 [代码质量]

因此设置变量涉及将调用的返回值分配给变量。

public TreeNode pruneTree(TreeNode root) {
    root = cleanTree(root);
    return root;
}

public TreeNode cleanTree(TreeNode node) {
    if (node == null) {
        return node;
    }
    node.left = cleanTree(root.left);
    node.right = cleanTree(root.right);
    if (node.val == 0) {
        if (node.left == null) {
            return node.right;
        }
        if (node.right == null) {
            return node.left;
        }
        // Bad luck ... should delete node.
    }
    return node;
}

这里不需要布尔结果。在最简单的情况下,返回传递的 TreeNode。

(为了清楚起见,我写了root = cleanTree(root);。)


删除中间的一个节点

public TreeNode cleanTree(TreeNode node) {
    if (node == null) {
        return node;
    }
    node.left = cleanTree(root.left);
    node.right = cleanTree(root.right);
    if (node.val == 0) {
        if (node.left == null) {
            return node.right;
        }
        if (node.right == null) {
            return node.left;
        }

现在上面的 if 只是一个启发式优化, 经常做更少的工作。

        // Delete node in the middle:
        // - either node.left as node.right's left-most leaf's left,
        // - or node.right as node.left's right-most leaf's right.
        // Sometimes called a pointer rotation (for 3 positions).
        if (depth(node.left) < depth(node.right) {
            TreeNode rightMin = node.right;
            while (rightMin.left != null) {
                rightMin = rightMin.left;
            }
            rightMin.left = node.left;
            return node.right;
        } else {
            TreeNode leftMax = node.left;
            while (leftMax.left != null) {
                leftMax = leftMax.right;
            }
            leftMax.right = node.right;
            return node.left;
        }            
    }
    return node;
}

private int depth(TreeNode node) {
    return node == null ? 0
             : 1 + Math.max(depth(node.left), depth(node.right);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2015-06-09
    • 1970-01-01
    相关资源
    最近更新 更多