我正试图找出如何在二叉搜索树中找到最长的路径(对bst和递归没有真正的经验),并找到了我根本不理解的解决方案。
const height = (node) => {
if(!node) return 0;
var leftHeight = height(node.left);
var rightHeight = height(node.right);
return Math.max(leftHeight, rightHeight) + 1;
}
height(node)
一个解释真是太神奇了!谢谢!
答案 0 :(得分:1)
基本上,您的调用栈将是最长的路径。
所以让我们来看看这棵树:
A
/ \
B C
/ \
D E
此处为JS:
{
name: 'A'
left: {
name: 'B',
left: null,
right: null,
}
right: {
name: 'C',
left: {
name: 'D',
left: null,
right: null,
},
right: {
name: 'E',
left: null,
right: null,
}
}
}
然后您执行node(nodeA)
。从现在开始,我将使用nodeX
来引用节点X
的对象。
然后将执行height(node.left);
,并且由于node.left
是nodeB
,因此基本上是height(nodeB)
。所以你的调用栈就是这个:
height(nodeA)
height(nodeB)
现在执行height(node.left);
(节点现在为nodeB
)。并且由于left
中的nodeB
是null
,因此本质上是height(nodeB)
。那么您的调用栈就是这样:
height(nodeA)
height(nodeB)
height(null)
现在,行if(!node) return 0;
将立即从函数返回,因为node
是null
,因此!node
是true
。返回值将为0
。
现在调用堆栈又是这个(最后一个堆栈元素已删除):
height(nodeA)
height(nodeB)
,值leftHeight
现在将为0(因为这就是返回的值)。
行var rightHeight = height(node.right);
实际上将执行相同的操作,因为node.right
也为null。因此Math.max(leftHeight, rightHeight)
本质上是Math.max(0, 0)
,所以0。这个加1
是1。这将被退回。调用堆栈现在如下所示:
height(nodeA)
和leftHeight
的值1
是正确的。
右侧也是如此,C
也是如此。但是,node.left
不会为空,而是nodeD
,因此将构建另一个堆栈帧:
height(nodeA)
height(nodeC)
height(nodeD)
此处nodeD
的左侧和右侧为null,将返回1,与nodeB
相同。 nodeE
也会发生同样的情况。然后nodeC
将leftHeight
设为1
,将rightHeight
设为1。该加1为2,因此height(nodeC)
将返回2
。
然后height(nodeA)
将leftHeight
设为1
,将rightHeight
设为2
。因此Math.max(leftHeight, rightHeight) + 1;
为3,结果正确。
基本上,您的代码是计数,而+1
是计数。计数的起点始终是return 0
。