题目描述(中等)
给你一棵 二叉树 的根节点 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 。
提示:
树中节点数目为 n 。
2 <= n <= 105
1 <= Node.val <= n
树中所有节点的值 互不相同 。
1 <= startValue, destValue <= n
startValue != destValue
思路
需要路径最短,则必须从最近公共祖先那里走。
第一步,找最近公共祖先,参考236. 二叉树的最近公共祖先,可以看下我之前的题解;
第二步,从最近公共祖先开始,分别找起止点,记录路径
如果往左子树,记录’L’,之后递归的在左子树找,如果没能找到,弹出’L’;右子树同理;
第三步,对于找起点的路径,全部重置为’U’,因为起点要向上找到祖先节点;对于找终点的路径,就是要走的路;
最后拼接两段路径即可。
代码
/**
* 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 {
public:
TreeNode* findfather(TreeNode* root, int p, int q) {
if(root == nullptr) return nullptr;
if(root->val == p || root->val == q) return root;
TreeNode* l = findfather(root->left,p,q);
TreeNode* r = findfather(root->right,p,q);
if(l&&r) return root;
else return l?l:r;
}
bool check(TreeNode* root,int x,string& s) {
if(root->val == x) return true;
if(root->left) {
s.push_back('L');
if(check(root->left,x,s)) return true;
s.pop_back();
}
if(root->right) {
s.push_back('R');
if(check(root->right,x,s)) return true;
s.pop_back();
}
return false;
}
string getDirections(TreeNode* root, int startValue, int destValue) {
TreeNode* commonfather = findfather(root,startValue,destValue);
string way2s;
string way2t;
check(commonfather,startValue,way2s);
check(commonfather,destValue,way2t);
fill(way2s.begin(),way2s.end(),'U');
return way2s+way2t;
}
};