Amazon Interview Question
Software Engineer / DevelopersCountry: India
Interview Type: Written Test
bottom up recursion. time complexity O(n)
int max=0;
Stack path;
Stack longestPath(node root){
if(root=null){
Stack s=new Stack();
return s;}
Stack l=longestPath(root.left);
Stack r=longestPath(root.right);
if(l.size()+r.size()+1>max) {
max = l.size()+r.size()+1;
Stack tmp=new Stack();
tmp.addAll(l);
tmp.push(root);
tmp.addAll(r);
path=tmp;}
l.push(root);
r.push(root);
return l.size()>r.size()?l:r;}
int maxHeight(struct node* root)
{
if(root == NULL)
{
return 0;
}
int lHeight = maxHeight(root->left);
int rHeight = maxHeight(root->right);
return (1 + (lHeight > rHeight ? lHeight : rHeight));
}
int max(int a, int b)
{
return (a > b ? a : b);
}
int maxTreeWalk(struct node* root)
{
if(root == NULL)
{
return 0;
}
int lHeight = maxHeight(root->left);
int rHeight = maxHeight(root->right);
int lDiameter = maxTreeWalk(root->left);
int rDiameter = maxTreeWalk(root->right);
return max(lHeight + rHeight + 1, max(lDiameter, rDiameter));
}
My approach would be:
Assign 2 variables with each node- leftLPL and rightLPL
and calculate for every node recursively:
if(node->left!=NULL)
node->leftLPL=max(node->left->leftLPL,node->left->rightLPL)+1;
else
node->leftLPL=0;
if(node->right!=NULL)
node->rightLPL=max(node->left->leftLPL,node->left->rightLPL)+1;
else
node->rightLPL=0;
same time look for the node which has max (node->leftLPL+node->rightLPL)
return that node lets say LPR;
and then...
PrintDiameterofTree(LPR)
Implementation Of above approach:
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>
struct graph
{
int value;
int leftLPL;
int rightLPL;
struct graph *left;
struct graph *right;
}*root,*lpr;
struct graph *creategraph(int k)
{
struct graph *temp=malloc(sizeof(struct graph));
temp->value=k;
temp->left=NULL;
temp->right=NULL;
return temp;
}
int m=0;
int max(int a, int b)
{
if(a>b)
return a;
else
return b;
}
struct graph *FindRootOfLP(struct graph *r)
{
if(r!=NULL)
{
if(r->left!=NULL)
FindRootOfLP(r->left);
if(r->right!=NULL);
FindRootOfLP(r->right);
if(r->left==NULL)
r->leftLPL=0;
else
r->leftLPL=max(r->left->leftLPL,r->left->rightLPL)+1;
if(r->right==NULL)
r->rightLPL=0;
else
r->rightLPL=max(r->right->leftLPL,r->right->rightLPL)+1;
if(r->leftLPL+r->rightLPL>m)
{
m=r->leftLPL+r->rightLPL;
lpr=r;
}
}
return lpr;
}
void PrintRightST(struct graph *R)
{
if(R==NULL)
return;
printf("%d ",R->value);
if(R->leftLPL>R->rightLPL)
PrintRightST(R->left);
else
PrintRightST(R->right);
}
void PrintLeftST(struct graph *L)
{
if(L==NULL)
return;
if(L->leftLPL>L->rightLPL)
PrintLeftST(L->left);
else
PrintLeftST(L->right);
printf("%d ",L->value);
}
void printLP(struct graph *l)
{
struct graph *tempL=l->left;
struct graph *tempR=l->right;
PrintLeftST(tempL);
printf("%d ",l->value);
PrintRightST(tempR);
}
void printLongestWalk(struct graph *k)
{
struct graph *lpr1=FindRootOfLP(k);
//printf("%d\n",lpr1->value);
printLP(lpr1);
}
int main()
{
root=creategraph(11);
root->left=creategraph(4);
root->right=creategraph(15);
root->left->left=creategraph(3);
root->left->right=creategraph(8);
root->left->left->left=creategraph(7);
root->left->left->left->left=creategraph(1);
root->left->right->right=creategraph(10);
root->left->right->right->right=creategraph(3);
printLongestWalk(root);
}
I think it is a tree diameter problem. You should be to find a C++ program in code.google.com/p/elements-of-programming-interviews/wiki/Programs where there is an entry called "Tree Diameter".
public class TreeCalc {
public Result calcMaxPath(Node node) {
if(node == null) {
return new Result(Collections.<Integer>emptyList(), Collections.<Integer>emptyList());
}
Result left = calcMaxPath(node.getLeft());
Result right = calcMaxPath(node.getRight());
List<Integer> longestBranch = new ArrayList<Integer>();
if(left.getLongestBranch().size() >= right.getLongestBranch().size()) {
longestBranch.addAll(left.getLongestBranch());
} else {
longestBranch.addAll(right.getLongestBranch());
}
longestBranch.add(node.getValue());
List<Integer> longestPath = new ArrayList<Integer>();
longestPath.addAll(left.getLongestBranch());
longestPath.add(node.getValue());
Collections.reverse(right.getLongestBranch());
longestPath.addAll(right.getLongestBranch());
if(left.longestPath.size() > longestPath.size()) {
longestPath = left.longestPath;
}
if(right.longestPath.size() > longestPath.size()) {
longestPath = right.longestPath;
}
return new Result(longestBranch, longestPath);
}
public static class Result {
private List<Integer> longestBranch;
private List<Integer> longestPath;
public Result(List<Integer> longestBranch, List<Integer> longestPath) {
this.longestBranch = longestBranch;
this.longestPath = longestPath;
}
public List<Integer> getLongestBranch() {
return longestBranch;
}
public void setLongestBranch(List<Integer> longestBranch) {
this.longestBranch = longestBranch;
}
public List<Integer> getLongestPath() {
return longestPath;
}
public void setLongestPath(List<Integer> longestPath) {
this.longestPath = longestPath;
}
}
}
I have seen, but the question is not asking to find the length of the max path,but to print the max length path @nitingupta
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class longestPath {
class node {
String val;
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
node right;
public node getRight() {
return right;
}
public void setRight(node right) {
this.right = right;
}
public node getLeft() {
return left;
}
public void setLeft(node left) {
this.left = left;
}
node left;
public node(String val) {
this.val = val;
}
}
public static void main(String[] args) {
longestPath path = new longestPath();
path.find();
}
public void find() {
node root = new node("A");
node b = new node("B");
node c = new node("C");
node d = new node("D");
node e = new node("E");
node f = new node("F");
node g = new node("G");
node h = new node("H");
node i = new node("I");
node j = new node("J");
node k = new node("K");
node l = new node("L");
node m = new node("M");
node n = new node("N");
root.setLeft(b);
root.setRight(c);
b.setLeft(d);
b.setRight(e);
c.setLeft(f);
c.setRight(g);
d.setLeft(h);
d.setRight(i);
i.setLeft(j);
c.setLeft(f);
c.setRight(g);
f.setLeft(k);
k.setLeft(l);
l.setLeft(m);
k.setRight(n);
List<node> leftPath = findLongestPath(root.getLeft());
for (int z = leftPath.size() - 1; z >= 0; z--) {
System.out.println(leftPath.get(z).getVal());
}
System.out.println(root.getVal());
for (node el : findLongestPath(root.getRight())) {
System.out.println(el.getVal());
}
}
private List<node> findLongestPath(node n) {
List<node> stacks = new ArrayList<node>();
node left = n.getLeft();
node right = n.getRight();
stacks.add(n);
if (left == null && right == null) {
return stacks;
} else {
List<node> sl = new ArrayList<longestPath.node>();
List<node> sr = new ArrayList<longestPath.node>();
if (left != null) {
//Find longest path to left of node.
sl = findLongestPath(left);
}
if (right != null) {
//Find longest path to right of node.
sr = findLongestPath(right);
}
if (sl.size() >= sr.size()) {
for (node e : sl) {
stacks.add(e);
}
} else {
for (node e : sr) {
stacks.add(e);
}
}
return stacks;
}
}
}
int maxDepth(Node root) {
if(root == null) {
return 0;
} else {
int ldepth = maxDepth(root.left);
int rdepth = maxDepth(root.right);
return ldepth>rdepth ? ldepth+1 : rdepth+1;
}
}
int longestPath(Node root)
{
if (root == null)
return 0;
int ldepth = maxDepth(root.left);
int rdepth = maxDepth(root.right);
int lLongPath = longestPath(root.left);
int rLongPath = longestPath(root.right);
return max(ldepth + rdepth + 1, max(lLongPath, rLongPath));
}
private static int getLongestPath(NodeT root) {
int maxPath[] = new int[1];
getLongestPath(root,maxPath);
return maxPath[0];
}
private static int getLongestPath(NodeT root, int[] maxPath) {
if(root == null)
return 0;
else{
int lH = getLongestPath(root.left,maxPath);
int rH = getLongestPath(root.right,maxPath);
if(maxPath[0]<lH+rH+1){
maxPath[0] = lH+rH+1;
}
return 1 + Math.max(lH, rH);
}
}
1
/ \
2 3
/ \
4 5
/ \ \
6 7 8
/ \ \
9 a b
At any given node :
path len with current node as root = max pathlen with node->left as root (L) + max pathlen with node->right as root (R) + 1
At each recursion function will return the maximum length possible with that node, whcih is either 1+ max(left) or 1 + max(right),
Also it will update the max length if the current path length is more that current max.
int maxlen;
len = maxpath(root,maxlen);
cout << maxlen;
int maxpath(node *root, int &maxlen) {
if (root==NULL) {
return 0;
}
int l = maxpath(root->left,maxlen);
int r = maxpath(root->right,maxlen);
int curmax = 1 + l + r;
if (curmax > maxlen) maxlen = curlen;
return max(1+l, 1+r);
}
This is on stackoverflow.com/questions/3124566/binary-tree-longest-path-between-2-nodes
- Anupam Srivastava January 24, 2013