import
java.util.ArrayList;
import
java.util.List;
class
Node {
Node left;
Node right;
int
value;
public
Node(
int
value) {
this
.value = value;
left =
null
;
right =
null
;
}
}
class
DeepestNodes {
List<Node> nodes =
new
ArrayList<>();
public
void
deepest(Node root,
int
level) {
if
(root ==
null
) {
return
;
}
if
(level ==
1
) {
nodes.add(root);
}
else
if
(level >
1
) {
deepest(root.left, level -
1
);
deepest(root.right, level -
1
);
}
}
}
public
class
BinaryTreeLongestPaths {
public
static
int
height(Node root) {
if
(root ==
null
) {
return
0
;
}
return
Math.max(height(root.left), height(root.right)) +
1
;
}
public
static
int
diameter(Node root) {
if
(root ==
null
) {
return
0
;
}
int
lHeight = height(root.left);
int
rHeight = height(root.right);
return
Math.max(lHeight + rHeight +
1
,
Math.max(diameter(root.left), diameter(root.right)));
}
public
static
void
printToNode(List<Integer> stack,
Node root, Node target,
int
flag) {
if
(root ==
null
) {
return
;
}
stack.add(root.value);
if
(root.value == target.value) {
if
(flag ==
0
) {
for
(
int
i =
1
; i < stack.size(); i++) {
System.out.print(stack.get(i) +
" "
);
}
}
else
if
(flag == -
1
) {
for
(
int
i = stack.size() -
1
; i >=
0
; i--) {
System.out.print(stack.get(i) +
" "
);
}
}
}
printToNode(stack, root.left, target, flag);
printToNode(stack, root.right, target, flag);
stack.remove(stack.size() -
1
);
}
public
static
void
printPath(Node root) {
DeepestNodes nodesLeft =
new
DeepestNodes();
nodesLeft.deepest(root.left, height(root.left));
List<Node> lDeepest = nodesLeft.nodes;
DeepestNodes nodesRight =
new
DeepestNodes();
nodesRight.deepest(root.right, height(root.right));
List<Node> rDeepest = nodesRight.nodes;
if
(lDeepest.size() ==
0
) {
for
(Node right : rDeepest) {
printToNode(
new
ArrayList<>(), root, right,
0
);
System.out.println();
}
return
;
}
if
(rDeepest.size() ==
0
) {
for
(Node left : lDeepest) {
printToNode(
new
ArrayList<>(), root, left, -
1
);
System.out.println();
}
return
;
}
for
(Node left : lDeepest) {
for
(Node right : rDeepest) {
printToNode(
new
ArrayList<>(), root, left, -
1
);
printToNode(
new
ArrayList<>(), root, right,
0
);
System.out.println();
}
}
}
public
static
void
printLongestPath(Node root,
int
diameterTree) {
if
(root ==
null
) {
return
;
}
int
heightSum = height(root.left) + height(root.right) +
1
;
if
(heightSum == diameterTree) {
printPath(root);
return
;
}
if
(root.left !=
null
) {
printLongestPath(root.left, diameterTree);
}
if
(root.right !=
null
) {
printLongestPath(root.right, diameterTree);
}
}
public
static
void
main(String[] args) {
Node rootNode =
new
Node(
1
);
rootNode.left =
new
Node(
2
);
rootNode.right =
new
Node(
3
);
rootNode.right.right =
new
Node(
11
);
rootNode.left.left =
new
Node(
4
);
rootNode.left.left.right =
new
Node(
8
);
rootNode.left.left.right.left =
new
Node(
9
);
rootNode.left.right =
new
Node(
5
);
rootNode.left.right.left =
new
Node(
6
);
rootNode.left.right.right =
new
Node(
7
);
rootNode.left.right.right.right =
new
Node(
10
);
System.out.println(
"Longest paths in the tree:"
);
printLongestPath(rootNode, diameter(rootNode));
}
}