从二叉树一个节点到另一个节点每一步的方向

137 阅读1分钟

给你一棵 二叉树 的根节点 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"
解释:最短路径为:31526

示例 2:

图片.png

输入: root = [2,1], startValue = 2, destValue = 1
输出: "L"
解释: 最短路径为:2 → 1 。

深度优先搜索

我们用 aba \rightarrow b 表示二叉树中 a 节点向上/向下到达 b 节点的路径,并用函数 d(ab)d(a \rightarrow b) 表示该路径的长度。假设起点 s 到终点 t 的最短路径经过了最近公共祖先 l 的祖先节点(不包括本身)u,那么这条路径的长度

d(slult)=d(sl)+d(lu)+d(ul)+d(lt)d(s→l→u→l→t)=d(s→l)+d(l→u)+d(u→l)+d(l→t)

var getDirections = function(root, startValue, destValue) {
    var lowestCommonAncestor = function(root, p, q) {
        let res;
        const dfs = (root, p, q) => {
            if (root === null) return false;
            const lson = dfs(root.left, p, q);
            const rson = dfs(root.right, p, q);
            if ((lson && rson) || ((root.val === p || root.val === q) && (lson || rson))) {
                res = root;
            } 
            return lson || rson || (root.val === p || root.val === q);
        }
        dfs(root, p, q);
        return res;
    };
    let f = lowestCommonAncestor(root,startValue,destValue);
    let ld = [];
    let rd = [];
    let dfs  = (root,val,ans)=>{
        if(!root)return false;
        if(root.val === val) return true;
        if(dfs(root.left,val,ans)){
            ans.push("L");
            return true;
        }else if(dfs(root.right,val,ans)) {
            ans.push("R");
            return true;
        } 
        return false;
    }
    dfs(f,startValue,ld);
    dfs(f,destValue,rd);
    ans = [].concat(new Array(ld.length).fill("U"),rd.reverse());
    return ans.join("");
};