📅  最后修改于: 2023-12-03 15:21:39.926000             🧑  作者: Mango
给定一个二叉树的根节点,找到其中字典序最小的回文路径,返回该路径上的节点值列表。
回文路径是指从根节点开始,往下走到某个叶节点,再返回到根节点所经过的路径。所经过的路径中只包含左右儿子的两种节点。
若多条回文路径字典序相同,则选择其中任意一条。
输入:
1
/ \
2 3
\ \
4 5
输出: [1,2,4,2,1]
我们可以通过 DFS 递归遍历二叉树来找到字典序最小的回文路径。
具体方法是:
遍历每个节点并记录其深度,同时记录该节点到根节点的路径上的所有节点;
如果当前节点是叶节点且该节点到根节点的路径上所有节点数量为奇数,则这条路径是回文路径,我们将其与之前记录的回文路径比较,选择字典序最小的;
回溯更新节点路径。
class Solution:
def findPalindromePath(self, root: TreeNode) -> List[int]:
# 记录字典序最小的回文路径
self.path = []
# 记录最小深度
self.minDepth = float('inf')
# 遍历记录每个节点到根节点的路径和深度
def dfs(node, depth, curPath):
if not node:
return
# 更新当前路径和深度
curPath.append(node.val)
if not node.left and not node.right:
# 当前节点是叶节点,判断路径是否为回文路径
if depth % 2 == 0:
# 路径长度为偶数,不可能是回文路径,直接返回
return
# 路径长度为奇数,判断是否为回文路径
for i in range(depth // 2):
if curPath[i] != curPath[-i-1]:
# 不是回文路径,直接返回
return
# 更新字典序最小的回文路径
if self.minDepth > depth:
self.minDepth = depth
self.path = curPath[:]
else:
# 递归遍历左右儿子节点
dfs(node.left, depth + 1, curPath)
dfs(node.right, depth + 1, curPath)
# 回溯,删除当前节点
curPath.pop()
# 从根节点开始遍历
dfs(root, 1, [])
return self.path
时间复杂度:$O(n)$,其中 $n$ 是二叉树节点数,需要遍历每个节点。
空间复杂度:$O(h)$,其中 $h$ 是二叉树高度,最坏情况下为 $n$,即链式二叉树,需要遍历所有节点保存对应路径。