求二叉樹節點的最大距離
題目:寫一個程序求一棵二叉樹中相距最遠的兩個節點之間的距離。
第一種實現方法(常規)
計算一個二叉樹的最大距離有兩個情況:
- 路徑經過根節點:路徑經過左子樹的最深節點,通過根節點,再到右子樹的最深節點。
- 路徑不經過根節點:而是左子樹或右子樹的最大距離路徑,取其大者。
所以,需要計算這兩個情況的路徑距離,並取其大者,就是該二叉樹的最大距離。
class Node {
public Node left; //左子樹
public Node right; //右子樹
public int lMax; //左子樹的最大距離
public int rMax; //右子樹的最大距離
public int val; //節點的值
}
int maxPath = 0;
/**
* 求二叉樹中節點的最大距離
* @param root
*/
public void findMaxPath(Node root){
if (root == null){
return;
}
// 如果左子樹爲空,那麼該節點的左邊最長距離爲0
if (root.left == null){
root.lMax = 0;
}
if (root.right == null){
root.rMax = 0;
}
// 如果左子樹不爲空,遞歸尋找左子樹最長距離
if (root.left != null){
findMaxPath(root.left);
}
if (root.right != null){
findMaxPath(root.right);
}
// 計算左子樹最長節點距離
if (root.left != null){
int len = 0;
if (root.left.lMax > root.left.rMax){
len = root.left.lMax;
}else{
len = root.left.rMax;
}
root.lMax = len + 1;
}
if (root.right != null){
int len = 0;
if (root.right.lMax > root.left.rMax){
len = root.right.lMax;
}else{
len = root.right.rMax;
}
root.rMax = len + 1;
}
// 更新最長距離
if (root.lMax + root.rMax > maxPath){
maxPath = root.lMax + root.rMax;
}
}
第二種實現方法(簡單解法)
第一種方案比較複雜,代碼也比較多。
我們可以換一種思路:此題中,最終是求2個節點間的路徑。雖然這個路徑可能不經過根節點,但是,必然會以一個節點爲根(根節點或子樹根節點),2個目標節點分佈在這個根節點的左子樹和右子樹中。所以,等同於“計算每個節點的左子樹和右子樹的高度和,然後取最大值”。
static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
int maxPath = 0;
/**
* 求二叉樹中節點的最大距離
* @param root
*/
public int findMaxPath2(TreeNode root){
if (root == null){
return -1;
}
int left = findMaxPath2(root.left) + 1;
int right = findMaxPath2(root.right) + 1;
if (left + right > maxPath){
maxPath = left + right;
}
return left > right ? left : right;
}