「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」
先上题,就是力扣687.
既是树又是最长,很容易想到要用递归。何况六个月前我还做过。 于是,拿出我的递归三步走。
1 先上边界条件, 叶子节点的同值路径为0
2 定义状态, 返回当前子树的最长同值路径。
3 递推关系,有点复杂 ,当父子节点同值时,父树和子树。。。。。。
但是这个状态能用吗? 不能用, 因为子树的最长同值路径和父节点代表的树的最长同值路径的关系,我找不到,三步走失败。
虽然这是个递归程序,但是需要递归的地方不一定就是整个程序。这个状态太大包大揽了,不好确定递推关系。大的问题解决不了,就应该尝试解决小的问题。
有一种思路就是,题目说可以不经过根节点,我们就定义状态为经过根节点的最长同值路径。 求出每个节点作为根节点的最长同值路径,取其最大值。 但是这个状态的递推关系仍然不好确定,这说明,也许我们可以再拆出更小的问题。 经过根节点的最长同值路径====> 从根节点出发的两条最长路径的和。 从根节点出发的最长路径,父子节点就有关系了。 在子节点的值等于根节点的情况下就等于子节点的路径加1,不同就是0。
因此,我们定义其状态为,f(root)代表从root出发的最长同值路径。 然后我们上一步想知道的是经过根节点的最长同值路径,也就是f(root.right) + f(root.left)。 然后我们在递归回溯的时候,每一次都取最大值。
代码就是这么简单。 对我而言难点在于,这个状态的确定过程。两个阶段的状态是有关联依赖性的, 如果定义的状态的上一阶段和这一阶段的关系不明,很可能就是定义错了状态。 不妨看看有没有,更小 的更容易解决的状态。