我想找到T,二叉树的鞍点,如果有的话。 鞍点在其所有祖先中具有最小值,但在其所有后代中具有最大值。如果叶子的价值低于它的所有祖先,那么叶子就可以成为这样的鞍点。
示例树:
F:15
E:16 H:17
B:14 G:16 I:8
A:8 C:7
D:5
B是一个这样的鞍点,因为14小于16和15,但也大于8,7和5. A,C,D和I是其他鞍点。
我试着想办法递归检查每个子树,并证明父节点是其所有后代中的最大值。但是,由于C(16)是其所有后代中的最大值但大于F(15),因此它不是鞍点,因此该方法不正确。
解决问题的最佳方法是什么?
答案 0 :(得分:1)
编写一个函数find_saddle
,它接受一个节点,以及父节点的最小值(默认为根节点的INT_MAX
)。它将返回最大的孩子的价值。当调用该函数时,它会计算出一个孩子可以拥有的最大值,并且可能是一个马鞍,它本身的最小值和最小父母。然后以最小值向左和向右递归,并收到每个子树中的最大值。如果节点自己的值大于bolth子树的最大值但小于父亲的最小值,那么它就是一个马鞍并且......无论你想要什么。最后,它返回它自己的最大值和两个子树最大值。
int find_saddle(node* n, int parent_min=INT_MAX) {
int child_min = min(n->value, parent_min);
int left_max = INT_MIN;
if (n->left)
left_max = find_saddle(n->left, child_min);
int right_max= INT_MIN;
if (n->right)
right_max = find_saddle(n->right, child_min);
int child_max = max(left_max, right_max);
if (n->value > child_max && n->value < parent_min)
do_thing(n);
return max(child_max, n->value);
}
此代码假设树叶可以是鞍点,但调整它以排除这些节点并不是很难。