我写了一个查找二叉树直径的代码。 需要以下建议:
算法是否正常/有何建议?
public class DiameterOfTree {
public static int diameter = 0;
public static int getDiameter(BinaryTreeNode root) {
if (root != null) {
int leftCount = getDiameter(root.getLeft());
int rightCount = getDiameter(root.getRight());
if (leftCount + rightCount > diameter) {
diameter = leftCount + rightCount;
System.out.println("---diameter------------->" + diameter);
}
if ( leftCount > rightCount) {
return leftCount + 1;
}
return rightCount + 1;
}
return 0;
}
}
答案 0 :(得分:39)
这是一个O(n)解决方案,对接受的答案进行了微小的更改:
public static int[] getDiameter(BinaryTreeNode root) {
int[] result = new int[]{0,0}; //1st element: diameter, 2nd: height
if (root == null) return result;
int[] leftResult = getDiameter(root.getLeft());
int[] rightResult = getDiameter(root.getRight());
int height = Math.max(leftResult[1], rightResult[1]) + 1;
int rootDiameter = leftResult[1] + rightResult[1] + 1;
int leftDiameter = leftResult[0];
int rightDiameter = rightResult[0];
result[0] = Math.max(rootDiameter, Math.max(leftDiameter, rightDiameter));
result[1] = height;
return result;
}
它只是同时计算高度和直径。由于Java没有pass-by-reference,我定义了一个int []来返回结果。
答案 1 :(得分:35)
尝试在二叉树(直径)中找到两个节点之间的最长路径时,需要考虑三种情况:
通过根的最长路径只是左右子树高度+ 1(根节点)的总和,其他两个可以递归地找到:
public static int getDiameter(BinaryTreeNode root) {
if (root == null)
return 0;
int rootDiameter = getHeight(root.getLeft()) + getHeight(root.getRight()) + 1;
int leftDiameter = getDiameter(root.getLeft());
int rightDiameter = getDiameter(root.getRight());
return Math.max(rootDiameter, Math.max(leftDiameter, rightDiameter));
}
public static int getHeight(BinaryTreeNode root) {
if (root == null)
return 0;
return Math.max(getHeight(root.getLeft()), getHeight(root.getRight())) + 1;
}
答案 2 :(得分:8)
以下是Java中具有O(N)
时间复杂度的解决方案。
它在计算直径时计算相同递归的高度。
参考Link
private class HeightWrapper {
int height = 0;
}
private int getDiameter_helper(BinaryTreeNode root, HeightWrapper wrapper) {
if (root == null) {
return 0; // diameter and height are 0
}
/* wrappers for heights of the left and right subtrees */
HeightWrapper lhWrapper = new HeightWrapper();
HeightWrapper rhWrapper = new HeightWrapper();
/* get heights of left and right subtrees and their diameters */
int leftDiameter = getDiameter_helper(root.left, lhWrapper);
int rightDiameter = getDiameter_helper(root.right, rhWrapper);
/* calculate root diameter */
int rootDiameter = lhWrapper.height + rhWrapper.height + 1;
/* calculate height of current node */
wrapper.height = Math.max(lhWrapper.height, rhWrapper.height) + 1;
/* calculate the diameter */
return Math.max(rootDiameter, Math.max(leftDiameter, rightDiameter));
}
public int getDiameter(BinaryTreeNode root) {
HeightWrapper wrapper = new HeightWrapper();
return getDiameter_helper(root, wrapper);
}
答案 3 :(得分:4)
您无需将结果存储在静态字段直径中。只需使用静态方法:
public class DiameterOfTree {
public static long getDiameter(BinaryTreeNode root) {
if (root != null) {
long leftDiameter = getDiameter(root.getLeft());
long rightDiameter = getDiameter(root.getRight());
long leftHeight = getHeight(root.getLeft());
long rightHeight = getHeight(root.getRight());
return Math.max(leftHeight + rightHeight + 1, Math.max(leftDiameter, rightDiameter));
}
return 0;
}
public static long getHeight(BinaryTreeNode root) {
if (root != null) {
long leftHeight = getHeight(root.getLeft());
long rightHeight = getHeight(root.getRight());
return 1 + Math.max(leftHeight, rightHeight);
}
return 0;
}
}
答案 4 :(得分:2)
树T的直径
直径(T)=最大(直径(T.left),直径(T.right), 高度(T.left)+高度(T.right)+1)
private class Data {
public int height;
public int diameter;
}
private void diameter(TreeNode root, Data d) {
if (root == null) {
d.height = 0; d.diameter = 0; return;
}
diameter(root.left, d); // get data in left subtree
int hLeft = d.height;
int dLeft = d.diameter;
diameter(root.right, d); // overwrite with data in right tree
d.diameter = Math.max(Math.max(dLeft, d.diameter), hLeft+d.height+1);
d.height = Math.max(hLeft, d.height) + 1;
}
public int diameter(TreeNode root) {
Data data = new Data();
diameter(root, data);
return data.diameter;
}
答案 5 :(得分:2)
与接受的答案相比,答案最小 O(n)。
int DiameterTree(BinaryTreeNode root, int diameter) {
int left, right;
if (!root) return 0;
left = DiameterTree(root.getLeft(), diameter);
right = DiameterTree(root.getRight(), diameter);
if (left + right > diameter) diameter = left + right;
return Math.max(left, right) + 1;
}
假设diameter
是类中的静态变量。
答案 6 :(得分:1)
public class NodeWrap{
int height = 0;
int maxLength = 0;
public NodeWrap(int h, int m){
height = s;
maxLength = m;
}
}
public NodeWrap getDiameter(BinaryNode root){
if(root == null){
return new NodeWrap(0, 0);
}
NodeWrap left = getDiameter(root.left);
NodeWrap right = getDiameter(root.right);
int height = Math.max(left.height + right.height) + 1;
int maxLength = Math.max(left.maxLength, right.maxLength);
if(left.height != 0 && right.height != 0){
maxLength = Math.max(left.height + right.height + 1, maxLength);
}
return new NodeWrap(singleLength, maxLength);
}
答案 7 :(得分:1)
One more O(n) solution in python,
code is self explanatory, only issue with this code is it returns tuple containing both height and diameter of the tree.
def diameter(node, height):
if node is None:
return 0, 0
leftheight = 0
rightheight = 0
leftdiameter, leftheight = diameter(node.left, leftheight)
rightdiameter, rightheight = diameter(node.right, rightheight)
rootheight = 1 + max(leftheight, rightheight )
rootdiameter = ( leftheight + rightheight + 1 )
return max( rootdiameter, leftdiameter, rightdiameter ), rootheight
答案 8 :(得分:0)
整洁干净的解决方案:
// way to use below util function:
prop p = new prop();
diameterUtil(root, p);
System.out.println(p.d);
class prop {
int h;
int d;
}
private void diameterUtil(Node n, prop p) {
if (n == null) {
p.h = 0;
p.d = 0;
return;
}
prop lp = new prop();
prop rp = new prop();
diameterUtil(n.left, lp);
diameterUtil(n.right, rp);
p.h = Math.max(lp.h, rp.h) + 1;
p.d = Math.max((lp.h + rp.h + 1), Math.max(lp.d, rp.d));
}
答案 9 :(得分:0)
这是C ++中的一个递归解决方案,它为您提供二叉树的高度和直径。
struct tree
{
int height = -1;
int diameter = 0;
};
struct tree BSTDiameter(struct node *root)
{
struct tree currentTree, leftTree, rightTree;
if (root == NULL)
{
currentTree.height = -1;
currentTree.diameter = 0;
return currentTree;
}
leftTree = BSTDiameter(root->left);
rightTree = BSTDiameter(root->right);
currentTree.height = ((leftTree.height > rightTree.height) ? leftTree.height : rightTree.height) + 1;
if (leftTree.height == -1 || rightTree.height == -1)
currentTree.diameter = 0;
else
currentTree.diameter = (leftTree.height + rightTree.height + 3) > (rightTree.diameter > leftTree.diameter ? rightTree.diameter : leftTree.diameter) ? (leftTree.height + rightTree.height + 3) : (rightTree.diameter > leftTree.diameter ? rightTree.diameter : leftTree.diameter);
return currentTree;
}
时间复杂度为O(h),其中h是树的高度。 希望对你有所帮助。
答案 10 :(得分:0)
最有效的方法是计算直径和高度,以得出O(n),这是最简单的方法[Python3,PyPy3]
for this definition for a binary tree node,
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
self.height = 1
def height(node):
if node is None:
return 0
l_height = height(node.left)
r_height = height(node.right)
self.height = max(self.height,l_height+r_height+1)
return max(l_height,r_height) + 1
height(root)
return self.height-1
最简单,最实惠的解决方案,具有更快的运行时间和更低的复杂性。