2096. 从二叉树一个节点到另一个节点每一步的方向(Rating 1804)
2096. 从二叉树一个节点到另一个节点每一步的方向(Rating 1804)
以下内容偏向于记录个人练习过程及思考,非常规题解内容
题目
思路
几个点想明白,代码就写出来了
二叉树中,一个节点到另一个节点,一定经过二者的“最近公共祖先”节点。
从根节点出发,分别找开始节点和目标节点比较容易,dfs一下,向左还是向右,记录路径即可。
从根节点分别到开始节点和目标节点,一定有一段重复的路,即根节点 -> 二者的最近公共祖先节点这部分
那么代码就有了
- dfs下整棵树,找到并记录【根节点到开始节点的路径】和【根节点到目标节点的路径】
- 去掉相同的前缀(即根节点 -> 二者的最近公共祖先节点这部分路径),即得到最近公共祖先节点分别到开始节点和目标节点的路径
- 【最近公共祖先节点到开始节点的路径】上的‘L’和‘R’都改为‘U’
- 合并路径即为答案
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 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 root is None:
return ''
to_st, to_ed = [], [] # 分别记录到st和到ed的路径
def dfs(node: Optional[TreeNode], path: list): # dfs
nonlocal to_st, to_ed # 声明nolocal,不然下面的copy()赋值会把赋值对象当成局部变量
if node.val == startValue: # 找到了开始节点,记录下路径
to_st = path.copy()
if node.val == destValue: # 找到了目标节点,记录下路径
to_ed = path.copy()
if node.left:
path.append('L') # 准备向左节点dfs,更新路径
dfs(node.left, path) # 向左节点dfs
path.pop() # 回溯,dfs完要恢复原路径
if node.right:
path.append('R') # 准备向右节点dfs,更新路径
dfs(node.right, path) # 向右节点dfs
path.pop() # 回溯,dfs完要恢复原路径
dfs(root, []) # 执行dfs
while len(to_st) and len(to_ed) and to_st[0] == to_ed[0]: # 使用python切片特性,去除公共前缀
to_st = to_st[1:]
to_ed = to_ed[1:]
return 'U' * len(to_st) + ''.join(to_ed) # 把前面的部分改为U
本文由作者按照 CC BY 4.0 进行授权