【LeetCode】2096. 从二叉树一个节点到另一个节点每一步的方向 Step-By-Step Directions From a Binary Tree Node to Another

  • 作者: 负雪明烛
  • 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 。

提示:

  1. 树中节点数目为 n
  2. 2 <= n <= 10^5
  3. 1 <= Node.val <= n
  4. 树中所有节点的值 互不相同 。
  5. 1 <= startValue, destValue <= n
  6. 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 日 —— 看到别人家买的房子真好看

猜你喜欢

转载自blog.csdn.net/fuxuemingzhu/article/details/121759290