【问题标题】:Binary Tree - Among the furthest from root, furthest to the right二叉树 - 离根最远,最右边
【发布时间】:2018-12-06 15:12:03
【问题描述】:

我有一棵二叉树。在离根最远的节点(我相信树的高度)中,我需要找到这些节点最右边的节点。

示例 1:

      M
     / \
    G   N
   / \   \
  D   H   O
 / \       \
B   F       Q

离根最远的节点中最右边的是'Q'。

示例 2:

      M
     / \
    G   N
   / \   \
  D   H   O
 / \       
B   F       

离根最远的节点中最右边的是'F'。

我的代码可以获得最深的节点并返回最右边的节点(如果最深的节点没有右子节点,则返回左边)。但后来我遇到了一个问题,可能有相同大小的叶子,我不知道如何回溯并比较所有叶子以找到最远的(在这种情况下是'Q')

我发现了如何找到树的最大高度,但不知道如何在我的代码中实现它

这是我目前所拥有的:

public void find(Node<T> r) {   

    if(r.right == null) { // Are there any children to the right?
        if(r.left.size() > 1) {
            find(r.left); // If not, we go left if there are more than 1
        }

        if(r.left.size() == 1) { //
            rNode = r.left.data;
        }

    }

    if(r.left == null) { // Are there any children to the left?
        if(r.right.size() > 1) {
            find(r.right); // If not, we go right if there are more than 1
        }

        if(r.right.size() == 1) {
            rNode = r.right.data; // If the right is the only node left, pick it as the answer
        }
    }

    if(r.left != null && r.right != null) { // Are there children to the left and right?
        if(r.left.size() == r.right.size()) { // 
            if(r.left.size() == 1) { // If we have 1 child to the right and left, pick the right child
                rNode = r.left.data; // If the left is the only node left, pick it as the answer
            } 
        }

        if(r.left.size() > r.right.size()) { // Are there more to the left?
            find(r.left); // Proceed
        }

        if(r.left.size() < r.right.size()) { // Are there more to the right?
            find(r.right); // Proceed
        }
    } 

}

public int maxDepth(Node<T> r) {

     if(r == null){
         return 0;
     }

     int leftDepth = maxDepth(r.left);
     int rightDepth = maxDepth(r.right);

     return Math.max(leftDepth, rightDepth)+1;     
 }


/**
 * Among all the nodes which are farthest from the root, find the one which is
 * farthest to the right.
 * 
 * @return data value of said node
 */
public T findRightmostLowest() {
    if(root.size() == 1) return root.data;

    find(root);
    return rNode;
}

【问题讨论】:

  • 为什么需要回溯?我认为如果 Q 或 O 离开了叶子,Q 仍然是最右边的。
  • @markspace 我想我没有,但我不确定如何获得正确的解决方案
  • 首先明确你真正想要什么。 “最右边”是树中最大(最大)的值。如果这就是你想要的,那么它就是 Q,不需要回溯。
  • 如果你想要最右边的,为什么还要向左走呢?一直往前走,直到你不能了。
  • @markspace 它是离根最远的最右边。所以在这种情况下,它是 B、F 和 Q。Q 在它们的右边,我试图在那里澄清它,但我的老师有办法做奇怪的作业。

标签: java binary-tree


【解决方案1】:

感谢您的帮助,它引导我找到正确的解决方案:

T rNode = null;
boolean found = false;

/**
 * Helper method that recursively finds Rightmost node between 
 * the nodes farthest from the root
 * 
 * @param r
 * @param depth
 * @param i - Our current level of the tree
 */
public void find(Node<T> r, int depth, int i) { 
    if(i == depth && found == false) { // Are we at the answer?
        rNode = r.data; // Dump node into our temporary node

        found = true;   // Change  found to true so we don't enter 
                        // the check a second time.
    }

    if(r.right != null) { // Are there children to the right?
        // If there is, does it lead to one of the farthest leaves?
        if((maxDepth(r.right) + i) == depth) {
            find(r.right, depth, i + 1); 
        }
    }

    if(r.left != null) { // Are there children to the left?
        // If there is, does it lead to one of the farthest leaves?
        if((maxDepth(r.left) + i) == depth) { 
            find(r.left, depth, i + 1);
        }
    }

}

/**
 * Find the height to our tree.
 * 
 * @param r
 * @return
 */
public int maxDepth(Node<T> r) {

     if(r == null){
         return 0;
     }

     int leftDepth = maxDepth(r.left);
     int rightDepth = maxDepth(r.right);

     return Math.max(leftDepth, rightDepth)+1;     
 }


/**
 * Among all the nodes which are farthest from the root, find the one which is
 * farthest to the right.
 * 
 * @return data value of said node
 */
public T findRightmostLowest() {

    rNode = null; // Reset the temporary node
    found = false; // Reset our boolean variable for helper method

    if(root.size() == 1) return root.data; // If tree has only 1 data point, return it

    find(root, maxDepth(root), 1); // Jump into the helper method

    return rNode; 
}

【讨论】:

    【解决方案2】:

    树问题几乎总是与非递归解决方案一样具有递归性。通常,递归的要简单得多。如果问题没问题,那么它可能看起来像这样:

    public static <T> Node<T> getRootFurthest(Node<T> root) {
        return findFurthest(root, 0, new NodeDepth<>()).node;
    }
    
    private static <T> NodeDepth<T> findFurthest(Node<T> node, int depth, NodeDepth<T> furthest) {
        if (node == null)
            return furthest;
    
        // >= - rigth node of equal depth
        // >  - left node of equal depth
        if (depth >= furthest.depth) {
            furthest.node = node;
            furthest.depth = depth;
        }
    
        findFurthest(node.left, depth + 1, furthest);
        findFurthest(node.right, depth + 1, furthest);
    
        return furthest;
    }
    

    还有两个受支持的类声明:

    private static final class NodeDepth<T> {
    
        private Node<T> node;
        private int depth = -1;
    }
    
    public static class Node<T> {
    
        private T val;
        private Node<T> left;
        private Node<T> right;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 2021-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多