Skip to content

Commit 9bc1ff1

Browse files
feat: add solutions to lc problem: No.2096 (doocs#3277)
Co-authored-by: Libin YANG <contact@yanglibin.info>
1 parent ee2f5e3 commit 9bc1ff1

File tree

8 files changed

+833
-361
lines changed

8 files changed

+833
-361
lines changed

solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md

+288-121
Large diffs are not rendered by default.

solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md

+288-121
Large diffs are not rendered by default.

solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.cpp

+30-32
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,43 @@
1111
*/
1212
class Solution {
1313
public:
14-
unordered_map<int, vector<pair<int, char>>> edges;
15-
unordered_set<int> visited;
16-
string ans;
17-
1814
string getDirections(TreeNode* root, int startValue, int destValue) {
19-
ans = "";
20-
traverse(root);
21-
string t = "";
22-
dfs(startValue, destValue, t);
23-
return ans;
15+
TreeNode* node = lca(root, startValue, destValue);
16+
string pathToStart, pathToDest;
17+
dfs(node, startValue, pathToStart);
18+
dfs(node, destValue, pathToDest);
19+
return string(pathToStart.size(), 'U') + pathToDest;
2420
}
2521

26-
void traverse(TreeNode* root) {
27-
if (!root) return;
28-
if (root->left) {
29-
edges[root->val].push_back({root->left->val, 'L'});
30-
edges[root->left->val].push_back({root->val, 'U'});
22+
private:
23+
TreeNode* lca(TreeNode* node, int p, int q) {
24+
if (node == nullptr || node->val == p || node->val == q) {
25+
return node;
3126
}
32-
if (root->right) {
33-
edges[root->val].push_back({root->right->val, 'R'});
34-
edges[root->right->val].push_back({root->val, 'U'});
27+
TreeNode* left = lca(node->left, p, q);
28+
TreeNode* right = lca(node->right, p, q);
29+
if (left != nullptr && right != nullptr) {
30+
return node;
3531
}
36-
traverse(root->left);
37-
traverse(root->right);
32+
return left != nullptr ? left : right;
3833
}
3934

40-
void dfs(int start, int dest, string& t) {
41-
if (visited.count(start)) return;
42-
if (start == dest) {
43-
if (ans == "" || ans.size() > t.size()) ans = t;
44-
return;
35+
bool dfs(TreeNode* node, int x, string& path) {
36+
if (node == nullptr) {
37+
return false;
38+
}
39+
if (node->val == x) {
40+
return true;
41+
}
42+
path.push_back('L');
43+
if (dfs(node->left, x, path)) {
44+
return true;
4545
}
46-
visited.insert(start);
47-
if (edges.count(start)) {
48-
for (auto& item : edges[start]) {
49-
t += item.second;
50-
dfs(item.first, dest, t);
51-
t.pop_back();
52-
}
46+
path.back() = 'R';
47+
if (dfs(node->right, x, path)) {
48+
return true;
5349
}
50+
path.pop_back();
51+
return false;
5452
}
55-
};
53+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* type TreeNode struct {
4+
* Val int
5+
* Left *TreeNode
6+
* Right *TreeNode
7+
* }
8+
*/
9+
func getDirections(root *TreeNode, startValue int, destValue int) string {
10+
var lca func(node *TreeNode, p, q int) *TreeNode
11+
lca = func(node *TreeNode, p, q int) *TreeNode {
12+
if node == nil || node.Val == p || node.Val == q {
13+
return node
14+
}
15+
left := lca(node.Left, p, q)
16+
right := lca(node.Right, p, q)
17+
if left != nil && right != nil {
18+
return node
19+
}
20+
if left != nil {
21+
return left
22+
}
23+
return right
24+
}
25+
var dfs func(node *TreeNode, x int, path *[]byte) bool
26+
dfs = func(node *TreeNode, x int, path *[]byte) bool {
27+
if node == nil {
28+
return false
29+
}
30+
if node.Val == x {
31+
return true
32+
}
33+
*path = append(*path, 'L')
34+
if dfs(node.Left, x, path) {
35+
return true
36+
}
37+
(*path)[len(*path)-1] = 'R'
38+
if dfs(node.Right, x, path) {
39+
return true
40+
}
41+
*path = (*path)[:len(*path)-1]
42+
return false
43+
}
44+
45+
node := lca(root, startValue, destValue)
46+
pathToStart := []byte{}
47+
pathToDest := []byte{}
48+
dfs(node, startValue, &pathToStart)
49+
dfs(node, destValue, &pathToDest)
50+
return string(bytes.Repeat([]byte{'U'}, len(pathToStart))) + string(pathToDest)
51+
}
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,41 @@
1-
/**
2-
* Definition for a binary tree node.
3-
* public class TreeNode {
4-
* int val;
5-
* TreeNode left;
6-
* TreeNode right;
7-
* TreeNode() {}
8-
* TreeNode(int val) { this.val = val; }
9-
* TreeNode(int val, TreeNode left, TreeNode right) {
10-
* this.val = val;
11-
* this.left = left;
12-
* this.right = right;
13-
* }
14-
* }
15-
*/
161
class Solution {
17-
private Map<Integer, List<List<String>>> edges;
18-
private Set<Integer> visited;
19-
private String ans;
20-
212
public String getDirections(TreeNode root, int startValue, int destValue) {
22-
edges = new HashMap<>();
23-
visited = new HashSet<>();
24-
ans = null;
25-
traverse(root);
26-
dfs(startValue, destValue, new ArrayList<>());
27-
return ans;
3+
TreeNode node = lca(root, startValue, destValue);
4+
StringBuilder pathToStart = new StringBuilder();
5+
StringBuilder pathToDest = new StringBuilder();
6+
dfs(node, startValue, pathToStart);
7+
dfs(node, destValue, pathToDest);
8+
return "U".repeat(pathToStart.length()) + pathToDest.toString();
289
}
2910

30-
private void traverse(TreeNode root) {
31-
if (root == null) {
32-
return;
33-
}
34-
if (root.left != null) {
35-
edges.computeIfAbsent(root.val, k -> new ArrayList<>())
36-
.add(Arrays.asList(String.valueOf(root.left.val), "L"));
37-
edges.computeIfAbsent(root.left.val, k -> new ArrayList<>())
38-
.add(Arrays.asList(String.valueOf(root.val), "U"));
11+
private TreeNode lca(TreeNode node, int p, int q) {
12+
if (node == null || node.val == p || node.val == q) {
13+
return node;
3914
}
40-
if (root.right != null) {
41-
edges.computeIfAbsent(root.val, k -> new ArrayList<>())
42-
.add(Arrays.asList(String.valueOf(root.right.val), "R"));
43-
edges.computeIfAbsent(root.right.val, k -> new ArrayList<>())
44-
.add(Arrays.asList(String.valueOf(root.val), "U"));
15+
TreeNode left = lca(node.left, p, q);
16+
TreeNode right = lca(node.right, p, q);
17+
if (left != null && right != null) {
18+
return node;
4519
}
46-
traverse(root.left);
47-
traverse(root.right);
20+
return left != null ? left : right;
4821
}
4922

50-
private void dfs(int start, int dest, List<String> t) {
51-
if (visited.contains(start)) {
52-
return;
23+
private boolean dfs(TreeNode node, int x, StringBuilder path) {
24+
if (node == null) {
25+
return false;
26+
}
27+
if (node.val == x) {
28+
return true;
5329
}
54-
if (start == dest) {
55-
if (ans == null || ans.length() > t.size()) {
56-
ans = String.join("", t);
57-
}
58-
return;
30+
path.append('L');
31+
if (dfs(node.left, x, path)) {
32+
return true;
5933
}
60-
visited.add(start);
61-
if (edges.containsKey(start)) {
62-
for (List<String> item : edges.get(start)) {
63-
t.add(item.get(1));
64-
dfs(Integer.parseInt(item.get(0)), dest, t);
65-
t.remove(t.size() - 1);
66-
}
34+
path.setCharAt(path.length() - 1, 'R');
35+
if (dfs(node.right, x, path)) {
36+
return true;
6737
}
38+
path.deleteCharAt(path.length() - 1);
39+
return false;
6840
}
69-
}
41+
}

solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.py

+31-30
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,41 @@
44
# self.val = val
55
# self.left = left
66
# self.right = right
7+
8+
79
class Solution:
810
def getDirections(
911
self, root: Optional[TreeNode], startValue: int, destValue: int
1012
) -> str:
11-
edges = defaultdict(list)
12-
ans = None
13-
visited = set()
13+
def lca(node: Optional[TreeNode], p: int, q: int):
14+
if node is None or node.val in (p, q):
15+
return node
16+
left = lca(node.left, p, q)
17+
right = lca(node.right, p, q)
18+
if left and right:
19+
return node
20+
return left or right
21+
22+
def dfs(node: Optional[TreeNode], x: int, path: List[str]):
23+
if node is None:
24+
return False
25+
if node.val == x:
26+
return True
27+
path.append("L")
28+
if dfs(node.left, x, path):
29+
return True
30+
path[-1] = "R"
31+
if dfs(node.right, x, path):
32+
return True
33+
path.pop()
34+
return False
35+
36+
node = lca(root, startValue, destValue)
1437

15-
def traverse(root):
16-
if not root:
17-
return
18-
if root.left:
19-
edges[root.val].append([root.left.val, 'L'])
20-
edges[root.left.val].append([root.val, 'U'])
21-
if root.right:
22-
edges[root.val].append([root.right.val, 'R'])
23-
edges[root.right.val].append([root.val, 'U'])
24-
traverse(root.left)
25-
traverse(root.right)
38+
path_to_start = []
39+
path_to_dest = []
2640

27-
def dfs(start, dest, t):
28-
nonlocal ans
29-
if start in visited:
30-
return
31-
if start == dest:
32-
if ans is None or len(ans) > len(t):
33-
ans = ''.join(t)
34-
return
35-
visited.add(start)
36-
for d, k in edges[start]:
37-
t.append(k)
38-
dfs(d, dest, t)
39-
t.pop()
41+
dfs(node, startValue, path_to_start)
42+
dfs(node, destValue, path_to_dest)
4043

41-
traverse(root)
42-
dfs(startValue, destValue, [])
43-
return ans
44+
return "U" * len(path_to_start) + "".join(path_to_dest)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* class TreeNode {
4+
* val: number
5+
* left: TreeNode | null
6+
* right: TreeNode | null
7+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
8+
* this.val = (val===undefined ? 0 : val)
9+
* this.left = (left===undefined ? null : left)
10+
* this.right = (right===undefined ? null : right)
11+
* }
12+
* }
13+
*/
14+
15+
function getDirections(root: TreeNode | null, startValue: number, destValue: number): string {
16+
const lca = (node: TreeNode | null, p: number, q: number): TreeNode | null => {
17+
if (node === null || node.val === p || node.val === q) {
18+
return node;
19+
}
20+
const left = lca(node.left, p, q);
21+
const right = lca(node.right, p, q);
22+
if (left !== null && right !== null) {
23+
return node;
24+
}
25+
return left !== null ? left : right;
26+
};
27+
28+
const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => {
29+
if (node === null) {
30+
return false;
31+
}
32+
if (node.val === x) {
33+
return true;
34+
}
35+
path.push('L');
36+
if (dfs(node.left, x, path)) {
37+
return true;
38+
}
39+
path[path.length - 1] = 'R';
40+
if (dfs(node.right, x, path)) {
41+
return true;
42+
}
43+
path.pop();
44+
return false;
45+
};
46+
47+
const node = lca(root, startValue, destValue);
48+
const pathToStart: string[] = [];
49+
const pathToDest: string[] = [];
50+
dfs(node, startValue, pathToStart);
51+
dfs(node, destValue, pathToDest);
52+
return 'U'.repeat(pathToStart.length) + pathToDest.join('');
53+
}

0 commit comments

Comments
 (0)