给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:
选择二叉树中 任意 节点和一个方向(左或者右)。
如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
改变前进方向:左变右或者右变左。
重复第二步和第三步,直到你在树中无法继续移动。
交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )。
请你返回给定树中最长 交错路径 的长度。
示例 1:
输入:root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1,null,1]
输出:3
解释:蓝色节点为树中最长交错路径(右 -> 左 -> 右)。
示例 2:
输入:root = [1,1,1,null,1,null,null,1,1,null,1]
输出:4
解释:蓝色节点为树中最长交错路径(左 -> 右 -> 左 -> 右)。
示例 3:
输入:root = [1]
输出:0
提示:
每棵树最多有 50000 个节点。
每个节点的值在 [1, 100] 之间。
思路1,采用动态规划,设根节点为 root, 当前 节点为 temp, 假设以 temp 节点为终结点(temp 节点是父节点的左子节点)的最长交错路径为 l_temp,temp 节点为终结点(temp 节点是父节点的右子节点)的最长交错路径为 r_temp, 显然,如果 temp1为 temp 的左子节点,l_temp1 = r_temp + 1, 如果是右子节点, r_temp1 = l_temp1 + 1
class Solution:
def longestZigZag(self, root: Optional[TreeNode]) -> int:
if root == None:
return 0
res = 0
l_mp = collections.defaultdict(int) ### 存放以当前位置为终点的最长交错路径长度(是root 节点的左子节点)
r_mp = collections.defaultdict(int)
q = collections.deque()
q.append(root)
while len(q) > 0:
top = q.popleft()
if top.left != None:
l_mp[top.left] = r_mp[top] + 1
q.append(top.left)
if top.right != None:
r_mp[top.right] = l_mp[top] + 1
q.append(top.right)
for x in l_mp:
res = max(res, l_mp[x])
for x in r_mp:
res = max(res, r_mp[x])
return res
另一种思路是递归
def longestZigZag(self, root: Optional[TreeNode]) -> int:
if root == None:
return 0
res = 0
def dfs(root, direction, depth):
if root == None:
return
nonlocal res
res = max(res, depth)
if direction == 0: # left
dfs(root.right, 1, depth+1)
dfs(root.right, 0, 0)
else:
dfs(root.left, 0, depth+1)
dfs(root.left, 1, 0)
dfs(root, 0, 0)
dfs(root, 1, 0)
return res