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);
}
}