LeetCode 2096. 从二叉树一个节点到另一个节点每一步的方向(最小公共祖先)

简介: LeetCode 2096. 从二叉树一个节点到另一个节点每一步的方向(最小公共祖先)

文章目录


1. 题目

2. 解题


1. 题目


给你一棵 二叉树 的根节点 root ,这棵二叉树总共有 n 个节点。

每个节点的值为 1 到 n 中的一个整数,且互不相同。

给你一个整数 startValue ,表示起点节点 s 的值,和另一个不同的整数 destValue ,表示终点节点 t 的值。


请找到从节点 s 到节点 t 的 最短路径 ,并以字符串的形式返回每一步的方向。

每一步用 大写 字母 ‘L’ ,‘R’ 和 ‘U’ 分别表示一种方向:


'L' 表示从一个节点前往它的 左孩子 节点。

'R' 表示从一个节点前往它的 右孩子 节点。

'U' 表示从一个节点前往它的 父 节点。

请你返回从 s 到 t 最短路径 每一步的方向。


示例 1:

image.png

输入:root = [5,1,2,3,null,6,4], 
startValue = 3, destValue = 6
输出:"UURL"
解释:最短路径为:3 → 1 → 5 → 2 → 6 。

image.png

输入: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


2. 解题


  • 先求解两个点的最小公共祖先 p
  • 然后 dfs1 求解 p 到 start 的步数 x,得到答案有 x 个 U
  • 再 dfs2 求解 p 到 end 的路径,就是答案的 后半部分
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    int stepdowntofindstart = -1;
    bool finddest = false;
    string pathtodest, path;
public:
    string getDirections(TreeNode* root, int startValue, int destValue) {
        TreeNode* p = lowestcommonParent(root, startValue, destValue);
        dfs1(p, startValue, 0);
        dfs2(p, destValue);
        if(stepdowntofindstart)
            return string(stepdowntofindstart, 'U') + pathtodest;
        return pathtodest;
    }
    TreeNode* lowestcommonParent(TreeNode* root, int sv, int dv)
    { // 最小公共祖先
        if(!root) return root;
        if(root->val == sv || root->val == dv)
            return root;
        auto l = lowestcommonParent(root->left, sv, dv);
        auto r = lowestcommonParent(root->right, sv, dv);
        if(l && r) return root;
        return l ? l : r;
    }
    void dfs1(TreeNode* root, int sv, int step)
    {  // 最小祖先到 start 的步数
        if(stepdowntofindstart != -1 || !root) return;
        if(root->val == sv)
        {
            stepdowntofindstart = step;
            return;
        }
        dfs1(root->left, sv, step+1);
        dfs1(root->right, sv, step+1);
    }
    void dfs2(TreeNode* root, int dv)
    {  // 最小祖先到 end 的路径 path
        if(finddest || !root) return;
        if(root->val == dv)
        {
            finddest = true;
            pathtodest = path;
            return;
        }
        path.push_back('L');
        dfs2(root->left, dv);
        path.pop_back();
        path.push_back('R');
        dfs2(root->right, dv);
        path.pop_back();
    }
};
相关文章
|
Go 开发者 索引
【LeetCode 热题100】路径与祖先:二叉树中的深度追踪技巧(力扣33 / 81/ 153/154)(Go语言版)
本文深入探讨了LeetCode中四道关于「搜索旋转排序数组」的经典题目,涵盖了无重复和有重复元素的情况。通过二分查找的变形应用,文章详细解析了每道题的解题思路和Go语言实现代码。关键点包括判断有序区间、处理重复元素以及如何缩小搜索范围。文章还总结了各题的异同,并推荐了类似题目,帮助读者全面掌握二分查找在旋转数组中的应用。无论是初学者还是有经验的开发者,都能从中获得实用的解题技巧和代码实现方法。
552 14
|
算法 Go
【LeetCode 热题100】深入理解二叉树结构变化与路径特性(力扣104 / 226 / 114 / 543)(Go语言版)
本博客深入探讨二叉树的深度计算、结构变换与路径分析,涵盖四道经典题目:104(最大深度)、226(翻转二叉树)、114(展开为链表)和543(二叉树直径)。通过递归与遍历策略(前序、后序等),解析每题的核心思路与实现方法。结合代码示例(Go语言),帮助读者掌握二叉树相关算法的精髓。下一讲将聚焦二叉树构造问题,欢迎持续关注!
419 10
|
存储 算法 数据可视化
【二叉树遍历入门:从中序遍历到层序与右视图】【LeetCode 热题100】94:二叉树的中序遍历、102:二叉树的层序遍历、199:二叉树的右视图(详细解析)(Go语言版)
本文详细解析了二叉树的三种经典遍历方式:中序遍历(94题)、层序遍历(102题)和右视图(199题)。通过递归与迭代实现中序遍历,深入理解深度优先搜索(DFS);借助队列完成层序遍历和右视图,掌握广度优先搜索(BFS)。文章对比DFS与BFS的思维方式,总结不同遍历的应用场景,为后续构造树结构奠定基础。
676 10
|
Go 索引 Perl
【LeetCode 热题100】【二叉树构造题精讲:前序 + 中序建树 & 有序数组构造 BST】(详细解析)(Go语言版)
本文详细解析了二叉树构造的两类经典问题:通过前序与中序遍历重建二叉树(LeetCode 105),以及将有序数组转化为平衡二叉搜索树(BST,LeetCode 108)。文章从核心思路、递归解法到实现细节逐一拆解,强调通过索引控制子树范围以优化性能,并对比两题的不同构造逻辑。最后总结通用构造套路,提供进阶思考方向,帮助彻底掌握二叉树构造类题目。
950 9
|
Go
【LeetCode 热题100】路径与祖先:二叉树中的深度追踪技巧(力扣437 / 236 )(Go语言版)
本文深入探讨二叉树中路径与祖先问题,涵盖两道经典题目:LeetCode 437(路径总和 III)和236(最近公共祖先)。对于路径总和 III,文章分析了双递归暴力解法与前缀和优化方法,后者通过哈希表记录路径和,将时间复杂度从O(n²)降至O(n)。在最近公共祖先问题中,采用后序遍历递归查找,利用“自底向上”的思路确定最近公共祖先节点。文中详细解析代码实现与核心要点,帮助读者掌握深度追踪技巧,理解树结构中路径与节点关系的本质。这类问题在面试中高频出现,掌握其解法意义重大。
342 4
【LeetCode 44】235.二叉搜索树的最近公共祖先
【LeetCode 44】235.二叉搜索树的最近公共祖先
181 1
【LeetCode 46】450.删除二叉搜索树的节点
【LeetCode 46】450.删除二叉搜索树的节点
237 0
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
214 0
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
160 0
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
453 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行

热门文章

最新文章