Skip to content

Commit 6c3d2ef

Browse files
committed
Apr-04
1 parent c23b57b commit 6c3d2ef

7 files changed

+453
-8
lines changed

README.md

+17-8
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Tag: Hash Table, Tree, Depth-First Search, Breadth-First Search, Binary Tree
2+
// Time: O(N)
3+
// Space: O(N)
4+
// Ref: Leetcode-865
5+
// Note: -
6+
// Video: https://youtu.be/FdSQ1jfDzd0
7+
8+
// Given the root of a binary tree, return the lowest common ancestor of its deepest leaves.
9+
// Recall that:
10+
//
11+
// The node of a binary tree is a leaf if and only if it has no children
12+
// The depth of the root of the tree is 0. if the depth of a node is d, the depth of each of its children is d + 1.
13+
// The lowest common ancestor of a set S of nodes, is the node A with the largest depth such that every node in S is in the subtree with root A.
14+
//
15+
//  
16+
// Example 1:
17+
//
18+
//
19+
// Input: root = [3,5,1,6,2,0,8,null,null,7,4]
20+
// Output: [2,7,4]
21+
// Explanation: We return the node with value 2, colored in yellow in the diagram.
22+
// The nodes coloured in blue are the deepest leaf-nodes of the tree.
23+
// Note that nodes 6, 0, and 8 are also leaf nodes, but the depth of them is 2, but the depth of nodes 7 and 4 is 3.
24+
// Example 2:
25+
//
26+
// Input: root = [1]
27+
// Output: [1]
28+
// Explanation: The root is the deepest node in the tree, and it's the lca of itself.
29+
//
30+
// Example 3:
31+
//
32+
// Input: root = [0,1,3,null,2]
33+
// Output: [2]
34+
// Explanation: The deepest leaf node in the tree is 2, the lca of one node is itself.
35+
//
36+
//  
37+
// Constraints:
38+
//
39+
// The number of nodes in the tree will be in the range [1, 1000].
40+
// 0 <= Node.val <= 1000
41+
// The values of the nodes in the tree are unique.
42+
//
43+
//  
44+
// Note: This question is the same as 865: https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/
45+
//
46+
47+
/**
48+
* Definition for a binary tree node.
49+
* struct TreeNode {
50+
* int val;
51+
* TreeNode *left;
52+
* TreeNode *right;
53+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
54+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
55+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
56+
* };
57+
*/
58+
class Solution {
59+
public:
60+
TreeNode* lcaDeepestLeaves(TreeNode* root) {
61+
return lca(root, 0).first;
62+
}
63+
64+
pair<TreeNode *, int> lca(TreeNode *node, int depth) {
65+
if (!node->left && !node->right) {
66+
return make_pair(node, depth);
67+
}
68+
69+
if (!node->left) {
70+
return lca(node->right, depth + 1);
71+
}
72+
73+
if (!node->right) {
74+
return lca(node->left, depth + 1);
75+
}
76+
77+
pair<TreeNode *, int> l = lca(node->left, depth + 1);
78+
pair<TreeNode *, int> r = lca(node->right, depth + 1);
79+
if (l.second == r.second) {
80+
return make_pair(node, l.second);
81+
} else if (l.second < r.second) {
82+
return r;
83+
} else {
84+
return l;
85+
}
86+
}
87+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Tag: Hash Table, Tree, Depth-First Search, Breadth-First Search, Binary Tree
2+
# Time: O(N)
3+
# Space: O(N)
4+
# Ref: Leetcode-865
5+
# Note: -
6+
# Video: https://youtu.be/FdSQ1jfDzd0
7+
8+
# Given the root of a binary tree, return the lowest common ancestor of its deepest leaves.
9+
# Recall that:
10+
#
11+
# The node of a binary tree is a leaf if and only if it has no children
12+
# The depth of the root of the tree is 0. if the depth of a node is d, the depth of each of its children is d + 1.
13+
# The lowest common ancestor of a set S of nodes, is the node A with the largest depth such that every node in S is in the subtree with root A.
14+
#
15+
#  
16+
# Example 1:
17+
#
18+
#
19+
# Input: root = [3,5,1,6,2,0,8,null,null,7,4]
20+
# Output: [2,7,4]
21+
# Explanation: We return the node with value 2, colored in yellow in the diagram.
22+
# The nodes coloured in blue are the deepest leaf-nodes of the tree.
23+
# Note that nodes 6, 0, and 8 are also leaf nodes, but the depth of them is 2, but the depth of nodes 7 and 4 is 3.
24+
# Example 2:
25+
#
26+
# Input: root = [1]
27+
# Output: [1]
28+
# Explanation: The root is the deepest node in the tree, and it's the lca of itself.
29+
#
30+
# Example 3:
31+
#
32+
# Input: root = [0,1,3,null,2]
33+
# Output: [2]
34+
# Explanation: The deepest leaf node in the tree is 2, the lca of one node is itself.
35+
#
36+
#  
37+
# Constraints:
38+
#
39+
# The number of nodes in the tree will be in the range [1, 1000].
40+
# 0 <= Node.val <= 1000
41+
# The values of the nodes in the tree are unique.
42+
#
43+
#  
44+
# Note: This question is the same as 865: https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/
45+
#
46+
47+
# Definition for a binary tree node.
48+
# class TreeNode:
49+
# def __init__(self, val=0, left=None, right=None):
50+
# self.val = val
51+
# self.left = left
52+
# self.right = right
53+
class Solution:
54+
def lcaDeepestLeaves(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
55+
return self.lca(root, 0)[0]
56+
57+
def lca(self, node: TreeNode, depth: int) -> Tuple:
58+
if node.left is None and node.right is None:
59+
return (node, depth)
60+
61+
if node.left is None:
62+
return self.lca(node.right, depth + 1)
63+
64+
if node.right is None:
65+
return self.lca(node.left, depth + 1)
66+
67+
n1, d1 = self.lca(node.left, depth + 1)
68+
n2, d2 = self.lca(node.right, depth + 1)
69+
70+
if d1 == d2:
71+
return (node, d1)
72+
elif d1 < d2:
73+
return (n2, d2)
74+
else:
75+
return (n1, d1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Tag: Array, Dynamic Programming, Greedy, Line Sweep
2+
// Time: O(N)
3+
// Space: O(N)
4+
// Ref: -
5+
// Note: -
6+
7+
// There is a one-dimensional garden on the x-axis. The garden starts at the point 0 and ends at the point n. (i.e., the length of the garden is n).
8+
// There are n + 1 taps located at points [0, 1, ..., n] in the garden.
9+
// Given an integer n and an integer array ranges of length n + 1 where ranges[i] (0-indexed) means the i-th tap can water the area [i - ranges[i], i + ranges[i]] if it was open.
10+
// Return the minimum number of taps that should be open to water the whole garden, If the garden cannot be watered return -1.
11+
//  
12+
// Example 1:
13+
//
14+
//
15+
// Input: n = 5, ranges = [3,4,1,1,0,0]
16+
// Output: 1
17+
// Explanation: The tap at point 0 can cover the interval [-3,3]
18+
// The tap at point 1 can cover the interval [-3,5]
19+
// The tap at point 2 can cover the interval [1,3]
20+
// The tap at point 3 can cover the interval [2,4]
21+
// The tap at point 4 can cover the interval [4,4]
22+
// The tap at point 5 can cover the interval [5,5]
23+
// Opening Only the second tap will water the whole garden [0,5]
24+
//
25+
// Example 2:
26+
//
27+
// Input: n = 3, ranges = [0,0,0,0]
28+
// Output: -1
29+
// Explanation: Even if you activate all the four taps you cannot water the whole garden.
30+
//
31+
//  
32+
// Constraints:
33+
//
34+
// 1 <= n <= 104
35+
// ranges.length == n + 1
36+
// 0 <= ranges[i] <= 100
37+
//
38+
//
39+
40+
class Solution {
41+
public:
42+
int minTaps(int n, vector<int>& ranges) {
43+
vector<int> line(n + 1, 0);
44+
for (int i = 0; i < ranges.size(); i++) {
45+
int start = max(0, i - ranges[i]);
46+
int end = min(n, i + ranges[i]);
47+
line[start] = max(line[start], end);
48+
}
49+
50+
int cur = 0;
51+
int right = 0;
52+
int i = 0;
53+
int res = 0;
54+
while (cur < n) {
55+
res += 1;
56+
while (i < line.size() && i <= cur) {
57+
right = max(right, line[i]);
58+
i += 1;
59+
}
60+
if (cur >= right) {
61+
return -1;
62+
}
63+
cur = right;
64+
}
65+
66+
return res;
67+
}
68+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Tag: Array, Dynamic Programming, Greedy, Line Sweep
2+
# Time: O(N)
3+
# Space: O(N)
4+
# Ref: -
5+
# Note: -
6+
7+
# There is a one-dimensional garden on the x-axis. The garden starts at the point 0 and ends at the point n. (i.e., the length of the garden is n).
8+
# There are n + 1 taps located at points [0, 1, ..., n] in the garden.
9+
# Given an integer n and an integer array ranges of length n + 1 where ranges[i] (0-indexed) means the i-th tap can water the area [i - ranges[i], i + ranges[i]] if it was open.
10+
# Return the minimum number of taps that should be open to water the whole garden, If the garden cannot be watered return -1.
11+
#  
12+
# Example 1:
13+
#
14+
#
15+
# Input: n = 5, ranges = [3,4,1,1,0,0]
16+
# Output: 1
17+
# Explanation: The tap at point 0 can cover the interval [-3,3]
18+
# The tap at point 1 can cover the interval [-3,5]
19+
# The tap at point 2 can cover the interval [1,3]
20+
# The tap at point 3 can cover the interval [2,4]
21+
# The tap at point 4 can cover the interval [4,4]
22+
# The tap at point 5 can cover the interval [5,5]
23+
# Opening Only the second tap will water the whole garden [0,5]
24+
#
25+
# Example 2:
26+
#
27+
# Input: n = 3, ranges = [0,0,0,0]
28+
# Output: -1
29+
# Explanation: Even if you activate all the four taps you cannot water the whole garden.
30+
#
31+
#  
32+
# Constraints:
33+
#
34+
# 1 <= n <= 104
35+
# ranges.length == n + 1
36+
# 0 <= ranges[i] <= 100
37+
#
38+
#
39+
40+
class Solution:
41+
def minTaps(self, n: int, ranges: List[int]) -> int:
42+
line = [0 for i in range(n + 1)]
43+
for i in range(len(ranges)):
44+
start = max(0, i - ranges[i])
45+
end = min(n, i + ranges[i])
46+
line[start] = max(line[start], end)
47+
48+
cur = 0
49+
res = 0
50+
right = 0
51+
i = 0
52+
while cur < n:
53+
res += 1
54+
while i <= n and i <= cur:
55+
right = max(right, line[i])
56+
i += 1
57+
58+
if (cur == right):
59+
return -1
60+
61+
cur = right
62+
63+
return res
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Tag: Hash Table, Tree, Depth-First Search, Breadth-First Search, Binary Tree
2+
// Time: O(N)
3+
// Space: O(N)
4+
// Ref: Leetcode-1123
5+
// Note: -
6+
// Video: https://youtu.be/FdSQ1jfDzd0
7+
8+
// Given the root of a binary tree, the depth of each node is the shortest distance to the root.
9+
// Return the smallest subtree such that it contains all the deepest nodes in the original tree.
10+
// A node is called the deepest if it has the largest depth possible among any node in the entire tree.
11+
// The subtree of a node is a tree consisting of that node, plus the set of all descendants of that node.
12+
//  
13+
// Example 1:
14+
//
15+
//
16+
// Input: root = [3,5,1,6,2,0,8,null,null,7,4]
17+
// Output: [2,7,4]
18+
// Explanation: We return the node with value 2, colored in yellow in the diagram.
19+
// The nodes coloured in blue are the deepest nodes of the tree.
20+
// Notice that nodes 5, 3 and 2 contain the deepest nodes in the tree but node 2 is the smallest subtree among them, so we return it.
21+
//
22+
// Example 2:
23+
//
24+
// Input: root = [1]
25+
// Output: [1]
26+
// Explanation: The root is the deepest node in the tree.
27+
//
28+
// Example 3:
29+
//
30+
// Input: root = [0,1,3,null,2]
31+
// Output: [2]
32+
// Explanation: The deepest node in the tree is 2, the valid subtrees are the subtrees of nodes 2, 1 and 0 but the subtree of node 2 is the smallest.
33+
//
34+
//  
35+
// Constraints:
36+
//
37+
// The number of nodes in the tree will be in the range [1, 500].
38+
// 0 <= Node.val <= 500
39+
// The values of the nodes in the tree are unique.
40+
//
41+
//  
42+
// Note: This question is the same as 1123: https://leetcode.com/problems/lowest-common-ancestor-of-deepest-leaves/
43+
//
44+
45+
/**
46+
* Definition for a binary tree node.
47+
* struct TreeNode {
48+
* int val;
49+
* TreeNode *left;
50+
* TreeNode *right;
51+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
52+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
53+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
54+
* };
55+
*/
56+
class Solution {
57+
public:
58+
TreeNode* subtreeWithAllDeepest(TreeNode* root) {
59+
return lca(root).first;
60+
}
61+
62+
pair<TreeNode *, int> lca(TreeNode *node) {
63+
if (!node) {
64+
return make_pair(node, 0);
65+
}
66+
67+
pair<TreeNode *, int> l = lca(node->left);
68+
pair<TreeNode *, int> r = lca(node->right);
69+
if (l.second == r.second) {
70+
return make_pair(node, l.second + 1);
71+
} else if (l.second < r.second) {
72+
return make_pair(r.first, r.second + 1);
73+
} else {
74+
return make_pair(l.first, l.second + 1);
75+
}
76+
}
77+
};

0 commit comments

Comments
 (0)