- 作者: 负雪明烛
- id: fuxuemingzhu
- 个人博客: http://fuxuemingzhu.cn/
- 公众号:负雪明烛
- 本文关键词:Leetcode, 力扣,刷题,Python, C++,链表,中间节点,删除
目录
题目地址:https://leetcode-cn.com/problems/step-by-step-directions-from-a-binary-tree-node-to-another/
题目描述
给你一棵 二叉树 的根节点 root
,这棵二叉树总共有 n
个节点。每个节点的值为 1 到 n 中的一个整数,且互不相同。给你一个整数 startValue
,表示起点节点 s 的值,和另一个不同的整数 destValue
,表示终点节点 t 的值。
请找到从节点 s 到节点 t 的 最短路径 ,并以字符串的形式返回每一步的方向。每一步用 大写 字母 'L'
,'R'
和 'U'
分别表示一种方向:
'L'
表示从一个节点前往它的 左孩子 节点。'R'
表示从一个节点前往它的 右孩子 节点。'U'
表示从一个节点前往它的 父 节点。
请你返回从 s 到 t 最短路径 每一步的方向。
示例 1:
输入:root = [5,1,2,3,null,6,4], startValue = 3, destValue = 6
输出:"UURL"
解释:最短路径为:3 → 1 → 5 → 2 → 6 。
示例 2:
输入:root = [2,1], startValue = 2, destValue = 1
输出:"L"
解释:最短路径为:2 → 1 。
提示:
- 树中节点数目为
n
。 2 <= n <= 10^5
1 <= Node.val <= n
- 树中所有节点的值 互不相同 。
1 <= startValue, destValue <= n
startValue != destValue
题目大意
找出二叉树中两个节点之间的路径。
解题方法
最低公共祖先 + 回溯法
第一想法是把树变成图,然后 BFS。看了眼数据的规模到了 10 ^ 5,就知道 BFS 一定不可行了。
很明显,两个节点之间最短的路径,就等于先从 startValue 到 最低公共祖先 再到 destValue。
问题就是找到最低公共祖先,以及找祖先到节点的路径。
最低公共祖先 236. Lowest Common Ancestor of a Binary Tree 是经典题目了,当然是要求会的。
那么就剩怎么找这个祖先到节点的路径了。也就是怎么在二叉树中找祖先节点到指定 value 节点的路径。
- 起始节点到祖先节点一定都是
'U'
,问题是有几个'U'
,'U'
等于祖先节点到起始节点路径长度。 - 祖先节点到目标节点一定都是
'L'
或者'R'
。
归根到底需要找到祖先节点到起始节点和目标节点的路径,我使用的回溯法。
在 root2node()
函数中,我用 path
保存遍历过的路径。如果寻找到目标节点的值 x
,那么就返回该路径的拷贝。如果没找到,那么就弹出path
最后一个值。
结果是:把祖先节点到起始节点的路径全部换成'U'
+ 祖先节点到目标节点的路径。
Python 代码如下:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def getDirections(self, root: Optional[TreeNode], startValue: int, destValue: int) -> str:
if not root:
return ""
ancestor = self.lowestCommonAncestor(root, startValue, destValue)
startPath = self.reverse(self.root2node(ancestor, startValue, []))
endPath = self.root2node(ancestor, destValue, [])
return "".join(startPath) + "".join(endPath)
def reverse(self, path):
return "U" * len(path)
@functools.lru_cache
def lowestCommonAncestor(self, root, p, q):
if not root or p == root.val or q == root.val:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
return left if left else right
def root2node(self, root, x, path):
if not root:
return ""
if root.val == x:
return copy.deepcopy(path)
left = ""
right = ""
if root.left:
path.append("L")
left = self.root2node(root.left, x, path)
path.pop()
if root.right:
path.append("R")
right = self.root2node(root.right, x, path)
path.pop()
return left if left else right
日期
2021 年 12 月 6 日 —— 看到别人家买的房子真好看