Skip to content

Commit 3347850

Browse files
authored
feat: add solutions to lc problems: No.2475~2477 (#2064)
1 parent 050ad19 commit 3347850

File tree

10 files changed

+338
-187
lines changed

10 files changed

+338
-187
lines changed

solution/2400-2499/2475.Number of Unequal Triplets in Array/README_EN.md

+22
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,28 @@ Note that (2, 0, 4) is not a valid triplet because 2 > 0.
4949

5050
## Solutions
5151

52+
**Solution 1: Brute Force Enumeration**
53+
54+
We can directly enumerate all triples $(i, j, k)$ and count all the ones that meet the conditions.
55+
56+
The time complexity is $O(n^3)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$.
57+
58+
**Solution 2: Sorting + Enumeration of Middle Elements + Binary Search**
59+
60+
We can also sort the array $nums$ first.
61+
62+
Then traverse $nums$, enumerate the middle element $nums[j]$, and use binary search to find the nearest index $i$ on the left side of $nums[j]$ such that $nums[i] < nums[j]$; find the nearest index $k$ on the right side of $nums[j]$ such that $nums[k] > nums[j]$. Then the number of triples with $nums[j]$ as the middle element and meeting the conditions is $(i + 1) \times (n - k)$, which is added to the answer.
63+
64+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the length of the array $nums$.
65+
66+
**Solution 3: Hash Table**
67+
68+
We can also use a hash table $cnt$ to count the number of each element in the array $nums$.
69+
70+
Then traverse the hash table $cnt$, enumerate the number of middle elements $b$, and denote the number of elements on the left as $a$. Then the number of elements on the right is $c = n - a - b$. At this time, the number of triples that meet the conditions is $a \times b \times c$, which is added to the answer. Then update $a = a + b$ and continue to enumerate the number of middle elements $b$.
71+
72+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
73+
5274
<!-- tabs:start -->
5375

5476
### **Python3**

solution/2400-2499/2476.Closest Nodes Queries in a Binary Search Tree/README.md

+69-33
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class Solution:
8181
def closestNodes(
8282
self, root: Optional[TreeNode], queries: List[int]
8383
) -> List[List[int]]:
84-
def dfs(root):
84+
def dfs(root: Optional[TreeNode]):
8585
if root is None:
8686
return
8787
dfs(root.left)
@@ -91,9 +91,9 @@ class Solution:
9191
nums = []
9292
dfs(root)
9393
ans = []
94-
for v in queries:
95-
i = bisect_right(nums, v) - 1
96-
j = bisect_left(nums, v)
94+
for x in queries:
95+
i = bisect_left(nums, x + 1) - 1
96+
j = bisect_left(nums, x)
9797
mi = nums[i] if 0 <= i < len(nums) else -1
9898
mx = nums[j] if 0 <= j < len(nums) else -1
9999
ans.append([mi, mx])
@@ -126,29 +126,18 @@ class Solution {
126126
public List<List<Integer>> closestNodes(TreeNode root, List<Integer> queries) {
127127
dfs(root);
128128
List<List<Integer>> ans = new ArrayList<>();
129-
for (int v : queries) {
130-
int i = search(v + 1) - 1;
131-
int j = search(v);
129+
for (int x : queries) {
130+
int i = Collections.binarySearch(nums, x + 1);
131+
int j = Collections.binarySearch(nums, x);
132+
i = i < 0 ? -i - 2 : i - 1;
133+
j = j < 0 ? -j - 1 : j;
132134
int mi = i >= 0 && i < nums.size() ? nums.get(i) : -1;
133135
int mx = j >= 0 && j < nums.size() ? nums.get(j) : -1;
134-
ans.add(Arrays.asList(mi, mx));
136+
ans.add(List.of(mi, mx));
135137
}
136138
return ans;
137139
}
138140

139-
private int search(int x) {
140-
int left = 0, right = nums.size();
141-
while (left < right) {
142-
int mid = (left + right) >> 1;
143-
if (nums.get(mid) >= x) {
144-
right = mid;
145-
} else {
146-
left = mid + 1;
147-
}
148-
}
149-
return left;
150-
}
151-
152141
private void dfs(TreeNode root) {
153142
if (root == null) {
154143
return;
@@ -178,18 +167,20 @@ class Solution {
178167
public:
179168
vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) {
180169
vector<int> nums;
181-
function<void(TreeNode * root)> dfs = [&](TreeNode* root) {
182-
if (!root) return;
170+
function<void(TreeNode*)> dfs = [&](TreeNode* root) {
171+
if (!root) {
172+
return;
173+
}
183174
dfs(root->left);
184-
nums.emplace_back(root->val);
175+
nums.push_back(root->val);
185176
dfs(root->right);
186177
};
187178
dfs(root);
188179
vector<vector<int>> ans;
189180
int n = nums.size();
190-
for (int& v : queries) {
191-
int i = upper_bound(nums.begin(), nums.end(), v) - nums.begin() - 1;
192-
int j = lower_bound(nums.begin(), nums.end(), v) - nums.begin();
181+
for (int& x : queries) {
182+
int i = lower_bound(nums.begin(), nums.end(), x + 1) - nums.begin() - 1;
183+
int j = lower_bound(nums.begin(), nums.end(), x) - nums.begin();
193184
int mi = i >= 0 && i < n ? nums[i] : -1;
194185
int mx = j >= 0 && j < n ? nums[j] : -1;
195186
ans.push_back({mi, mx});
@@ -222,15 +213,14 @@ func closestNodes(root *TreeNode, queries []int) (ans [][]int) {
222213
dfs(root.Right)
223214
}
224215
dfs(root)
225-
n := len(nums)
226-
for _, v := range queries {
227-
i := sort.SearchInts(nums, v+1) - 1
228-
j := sort.SearchInts(nums, v)
216+
for _, x := range queries {
217+
i := sort.SearchInts(nums, x+1) - 1
218+
j := sort.SearchInts(nums, x)
229219
mi, mx := -1, -1
230-
if i >= 0 && i < n {
220+
if i >= 0 {
231221
mi = nums[i]
232222
}
233-
if j >= 0 && j < n {
223+
if j < len(nums) {
234224
mx = nums[j]
235225
}
236226
ans = append(ans, []int{mi, mx})
@@ -242,7 +232,53 @@ func closestNodes(root *TreeNode, queries []int) (ans [][]int) {
242232
### **TypeScript**
243233

244234
```ts
235+
/**
236+
* Definition for a binary tree node.
237+
* class TreeNode {
238+
* val: number
239+
* left: TreeNode | null
240+
* right: TreeNode | null
241+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
242+
* this.val = (val===undefined ? 0 : val)
243+
* this.left = (left===undefined ? null : left)
244+
* this.right = (right===undefined ? null : right)
245+
* }
246+
* }
247+
*/
245248

249+
function closestNodes(root: TreeNode | null, queries: number[]): number[][] {
250+
const nums: number[] = [];
251+
const dfs = (root: TreeNode | null) => {
252+
if (!root) {
253+
return;
254+
}
255+
dfs(root.left);
256+
nums.push(root.val);
257+
dfs(root.right);
258+
};
259+
const search = (x: number): number => {
260+
let [l, r] = [0, nums.length];
261+
while (l < r) {
262+
const mid = (l + r) >> 1;
263+
if (nums[mid] >= x) {
264+
r = mid;
265+
} else {
266+
l = mid + 1;
267+
}
268+
}
269+
return l;
270+
};
271+
dfs(root);
272+
const ans: number[][] = [];
273+
for (const x of queries) {
274+
const i = search(x + 1) - 1;
275+
const j = search(x);
276+
const mi = i >= 0 ? nums[i] : -1;
277+
const mx = j < nums.length ? nums[j] : -1;
278+
ans.push([mi, mx]);
279+
}
280+
return ans;
281+
}
246282
```
247283

248284
### **...**

solution/2400-2499/2476.Closest Nodes Queries in a Binary Search Tree/README_EN.md

+75-33
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@
4848

4949
## Solutions
5050

51+
**Solution 1: In-order Traversal + Binary Search**
52+
53+
Since the problem provides a binary search tree, we can obtain a sorted array through in-order traversal. Then for each query, we can find the maximum value less than or equal to the query value and the minimum value greater than or equal to the query value through binary search.
54+
55+
The time complexity is $O(n + m \times \log n)$, and the space complexity is $O(n)$. Here, $n$ and $m$ are the number of nodes in the binary search tree and the number of queries, respectively.
56+
5157
<!-- tabs:start -->
5258

5359
### **Python3**
@@ -63,7 +69,7 @@ class Solution:
6369
def closestNodes(
6470
self, root: Optional[TreeNode], queries: List[int]
6571
) -> List[List[int]]:
66-
def dfs(root):
72+
def dfs(root: Optional[TreeNode]):
6773
if root is None:
6874
return
6975
dfs(root.left)
@@ -73,9 +79,9 @@ class Solution:
7379
nums = []
7480
dfs(root)
7581
ans = []
76-
for v in queries:
77-
i = bisect_right(nums, v) - 1
78-
j = bisect_left(nums, v)
82+
for x in queries:
83+
i = bisect_left(nums, x + 1) - 1
84+
j = bisect_left(nums, x)
7985
mi = nums[i] if 0 <= i < len(nums) else -1
8086
mx = nums[j] if 0 <= j < len(nums) else -1
8187
ans.append([mi, mx])
@@ -106,29 +112,18 @@ class Solution {
106112
public List<List<Integer>> closestNodes(TreeNode root, List<Integer> queries) {
107113
dfs(root);
108114
List<List<Integer>> ans = new ArrayList<>();
109-
for (int v : queries) {
110-
int i = search(v + 1) - 1;
111-
int j = search(v);
115+
for (int x : queries) {
116+
int i = Collections.binarySearch(nums, x + 1);
117+
int j = Collections.binarySearch(nums, x);
118+
i = i < 0 ? -i - 2 : i - 1;
119+
j = j < 0 ? -j - 1 : j;
112120
int mi = i >= 0 && i < nums.size() ? nums.get(i) : -1;
113121
int mx = j >= 0 && j < nums.size() ? nums.get(j) : -1;
114-
ans.add(Arrays.asList(mi, mx));
122+
ans.add(List.of(mi, mx));
115123
}
116124
return ans;
117125
}
118126

119-
private int search(int x) {
120-
int left = 0, right = nums.size();
121-
while (left < right) {
122-
int mid = (left + right) >> 1;
123-
if (nums.get(mid) >= x) {
124-
right = mid;
125-
} else {
126-
left = mid + 1;
127-
}
128-
}
129-
return left;
130-
}
131-
132127
private void dfs(TreeNode root) {
133128
if (root == null) {
134129
return;
@@ -158,18 +153,20 @@ class Solution {
158153
public:
159154
vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) {
160155
vector<int> nums;
161-
function<void(TreeNode * root)> dfs = [&](TreeNode* root) {
162-
if (!root) return;
156+
function<void(TreeNode*)> dfs = [&](TreeNode* root) {
157+
if (!root) {
158+
return;
159+
}
163160
dfs(root->left);
164-
nums.emplace_back(root->val);
161+
nums.push_back(root->val);
165162
dfs(root->right);
166163
};
167164
dfs(root);
168165
vector<vector<int>> ans;
169166
int n = nums.size();
170-
for (int& v : queries) {
171-
int i = upper_bound(nums.begin(), nums.end(), v) - nums.begin() - 1;
172-
int j = lower_bound(nums.begin(), nums.end(), v) - nums.begin();
167+
for (int& x : queries) {
168+
int i = lower_bound(nums.begin(), nums.end(), x + 1) - nums.begin() - 1;
169+
int j = lower_bound(nums.begin(), nums.end(), x) - nums.begin();
173170
int mi = i >= 0 && i < n ? nums[i] : -1;
174171
int mx = j >= 0 && j < n ? nums[j] : -1;
175172
ans.push_back({mi, mx});
@@ -202,15 +199,14 @@ func closestNodes(root *TreeNode, queries []int) (ans [][]int) {
202199
dfs(root.Right)
203200
}
204201
dfs(root)
205-
n := len(nums)
206-
for _, v := range queries {
207-
i := sort.SearchInts(nums, v+1) - 1
208-
j := sort.SearchInts(nums, v)
202+
for _, x := range queries {
203+
i := sort.SearchInts(nums, x+1) - 1
204+
j := sort.SearchInts(nums, x)
209205
mi, mx := -1, -1
210-
if i >= 0 && i < n {
206+
if i >= 0 {
211207
mi = nums[i]
212208
}
213-
if j >= 0 && j < n {
209+
if j < len(nums) {
214210
mx = nums[j]
215211
}
216212
ans = append(ans, []int{mi, mx})
@@ -222,7 +218,53 @@ func closestNodes(root *TreeNode, queries []int) (ans [][]int) {
222218
### **TypeScript**
223219

224220
```ts
221+
/**
222+
* Definition for a binary tree node.
223+
* class TreeNode {
224+
* val: number
225+
* left: TreeNode | null
226+
* right: TreeNode | null
227+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
228+
* this.val = (val===undefined ? 0 : val)
229+
* this.left = (left===undefined ? null : left)
230+
* this.right = (right===undefined ? null : right)
231+
* }
232+
* }
233+
*/
225234

235+
function closestNodes(root: TreeNode | null, queries: number[]): number[][] {
236+
const nums: number[] = [];
237+
const dfs = (root: TreeNode | null) => {
238+
if (!root) {
239+
return;
240+
}
241+
dfs(root.left);
242+
nums.push(root.val);
243+
dfs(root.right);
244+
};
245+
const search = (x: number): number => {
246+
let [l, r] = [0, nums.length];
247+
while (l < r) {
248+
const mid = (l + r) >> 1;
249+
if (nums[mid] >= x) {
250+
r = mid;
251+
} else {
252+
l = mid + 1;
253+
}
254+
}
255+
return l;
256+
};
257+
dfs(root);
258+
const ans: number[][] = [];
259+
for (const x of queries) {
260+
const i = search(x + 1) - 1;
261+
const j = search(x);
262+
const mi = i >= 0 ? nums[i] : -1;
263+
const mx = j < nums.length ? nums[j] : -1;
264+
ans.push([mi, mx]);
265+
}
266+
return ans;
267+
}
226268
```
227269

228270
### **...**

0 commit comments

Comments
 (0)