Step-By-Step Directions From a Binary Tree Node to Another

这篇博客讨论了如何在二叉树中找到从指定起始节点到目标节点的最短路径。提出了两种解决方案:一是通过查找最近公共祖先(LCA)并回溯路径,二是将树转换为图并进行深度优先搜索(DFS)。这两种方法都涉及到递归和路径构建,确保找到的路径是最短的。
摘要由CSDN通过智能技术生成

You are given the root of a binary tree with n nodes. Each node is uniquely assigned a value from 1 to n. You are also given an integer startValue representing the value of the start node s, and a different integer destValue representing the value of the destination node t.

Find the shortest path starting from node s and ending at node t. Generate step-by-step directions of such path as a string consisting of only the uppercase letters 'L''R', and 'U'. Each letter indicates a specific direction:

  • 'L' means to go from a node to its left child node.
  • 'R' means to go from a node to its right child node.
  • 'U' means to go from a node to its parent node.

Return the step-by-step directions of the shortest path from node s to node t.

Example 1:

Input: root = [5,1,2,3,null,6,4], startValue = 3, destValue = 6
Output: "UURL"
Explanation: The shortest path is: 3 → 1 → 5 → 2 → 6.

Example 2:

Input: root = [2,1], startValue = 2, destValue = 1
Output: "L"
Explanation: The shortest path is: 2 → 1.

Constraints:

  • The number of nodes in the tree is n.
  • 2 <= n <= 105
  • 1 <= Node.val <= n
  • All the values in the tree are unique.
  • 1 <= startValue, destValue <= n
  • startValue != destValue

思路1:找到LCA,然后从LCA走,左边都是往上U,但是右边有path,怎么找就是backtracking,用deque去收集path,然后找到了就return true,不backtracking了,保留path返回。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public String getDirections(TreeNode root, int startValue, int destValue) {
        TreeNode LCA = findLCA(root, startValue, destValue);
        ArrayDeque<String> sdeque = new ArrayDeque<>();
        findPath(LCA, startValue, sdeque);
        
        ArrayDeque<String> ddeque = new ArrayDeque<>();
        findPath(LCA, destValue, ddeque);
        
        StringBuilder sb = new StringBuilder();
        while(!sdeque.isEmpty()) {
            sdeque.poll();
            sb.append("U");
        }
        
        while(!ddeque.isEmpty()) {
            sb.append(ddeque.poll());
        }
        return sb.toString();
    }
    
    private TreeNode findLCA(TreeNode root, int startValue, int destValue) {
        if(root == null || root.val == startValue || root.val == destValue) {
            return root;
        }
        TreeNode leftnode = findLCA(root.left, startValue, destValue);
        TreeNode rightnode = findLCA(root.right, startValue, destValue);
        if(leftnode == null) {
            return rightnode;
        } else if(rightnode == null) {
            return leftnode;
        } else {
            return root;
        }
    }
    
    private boolean findPath(TreeNode root, int target, ArrayDeque<String> deque) {
        if(root == null) {
            return false;
        }
        if(root.val == target) {
            return true;
        }
        
        deque.offer("L");
        if(findPath(root.left, target, deque)) {
            return true;
        }
        deque.removeLast();
        
        deque.offer("R");
        if(findPath(root.right, target, deque)) {
            return true;
        }
        deque.removeLast();
        
        return false;
    }
    
}

 思路2:把tree换成图的问题解决,build graph,保留neighbor之间的关系,然后用dfs去找,因为是unique的,肯定找到就是最短path。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private String finalPath = null;
    public String getDirections(TreeNode root, int startValue, int destValue) {
        HashMap<Integer, HashMap<Integer, String>> graph = new HashMap<>();
        buildGraph(root, graph);
        StringBuilder sb = new StringBuilder();
        HashSet<Integer> visited = new HashSet<>();
        dfs(graph, sb, startValue, destValue, visited);
        return finalPath;
    }
    
    private void dfs(HashMap<Integer, HashMap<Integer, String>> graph,
                    StringBuilder sb,
                    int startValue, 
                    int destValue,
                    HashSet<Integer> visited) {
        if(startValue == destValue) {
            finalPath = sb.toString();
            return;
        }
        HashMap<Integer, String> neighbors = graph.get(startValue);
        visited.add(startValue);
        for(Integer neighbor: neighbors.keySet()) {
            if(visited.contains(neighbor)) {
                continue;
            }
            sb.append(neighbors.get(neighbor));
            visited.add(neighbor);
            dfs(graph, sb, neighbor, destValue, visited);
            visited.remove(neighbor);
            sb.deleteCharAt(sb.length() - 1);
        }
    }
    
    private void buildGraph(TreeNode root, HashMap<Integer, HashMap<Integer, String>> graph) {
        if(root == null) {
            return;
        }
        TreeNode leftNode = root.left;
        TreeNode rightNode = root.right;
        
        if(leftNode != null) {
            graph.putIfAbsent(root.val, new HashMap<Integer, String>());
            graph.get(root.val).put(leftNode.val, "L");
            
            graph.putIfAbsent(leftNode.val, new HashMap<Integer, String>());
            graph.get(leftNode.val).put(root.val, "U");
        }
        
        if(rightNode != null) {
            graph.putIfAbsent(root.val, new HashMap<Integer, String>());
            graph.get(root.val).put(rightNode.val, "R");
            
            graph.putIfAbsent(rightNode.val, new HashMap<Integer, String>());
            graph.get(rightNode.val).put(root.val, "U");
        }
        
        buildGraph(root.left, graph);
        buildGraph(root.right, graph);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值