Skip to content

Commit f83fc91

Browse files
authored
feat: add solutions to lc problem: No.2940 (doocs#1987)
No.2940.Find Building Where Alice and Bob Can Meet
1 parent 82a2749 commit f83fc91

File tree

11 files changed

+979
-5
lines changed

11 files changed

+979
-5
lines changed

solution/2700-2799/2736.Maximum Sum Queries/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ $$
7777

7878
时间复杂度 $O((n + m) \times \log n + m \times \log m)$,空间复杂度 $O(n + m)$。其中 $n$ 是数组 $nums$ 的长度,而 $m$ 是数组 $queries$ 的长度。
7979

80+
相似题目:
81+
82+
- [2940. 找到 Alice 和 Bob 可以相遇的建筑](/solution/2900-2999/2940.Find%20Building%20Where%20Alice%20and%20Bob%20Can%20Meet/README.md)
83+
8084
<!-- tabs:start -->
8185

8286
### **Python3**

solution/2700-2799/2736.Maximum Sum Queries/README_EN.md

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ Next, we iterate through each query $queries[i] = (x, y)$. For the current query
7777

7878
The time complexity is $O((n + m) \times \log n + m \times \log m)$, and the space complexity is $O(n + m)$. Here, $n$ is the length of the array $nums$, and $m$ is the length of the array $queries$.
7979

80+
Similar problems:
81+
82+
- [2940. Find Building Where Alice and Bob Can Meet](/solution/2900-2999/2940.Find%20Building%20Where%20Alice%20and%20Bob%20Can%20Meet/README_EN.md)
83+
8084
<!-- tabs:start -->
8185

8286
### **Python3**

solution/2900-2999/2940.Find Building Where Alice and Bob Can Meet/README.md

+330-3
Original file line numberDiff line numberDiff line change
@@ -60,34 +60,361 @@
6060

6161
<!-- 这里可写通用的实现逻辑 -->
6262

63+
**方法一:树状数组**
64+
65+
我们不妨记 $queries[i] = [l_i, r_i]$,其中 $l_i \le r_i$。如果 $l_i = r_i$ 或者 $heights[l_i] \lt heights[r_i]$,那么答案就是 $r_i$。否则,我们需要在所有满足 $j \gt r_i$,且 $heights[j] \gt heights[l_i]$ 的 $j$ 中找到最小的 $j$。
66+
67+
我们可以将 $queries$ 按照 $r_i$ 从大到小排序,用一个指针 $j$ 指向当前遍历到的 $heights$ 的下标。
68+
69+
接下来,我们遍历每个查询 $queries[i] = (l, r)$,对于当前查询,如果 $j \gt r$,那么我们循环将 $heights[j]$ 插入树状数组中。树状数组维护的是后缀高度(离散化后的高度)的下标的最小值。然后,我们判断是否满足 $l = r$ 或者 $heights[l] \lt heights[r]$,如果满足,那么当前查询的答案就是 $r$,否则,我们在树状数组中查询 $heights[l]$ 的下标的最小值,即为当前查询的答案。
70+
71+
时间复杂度 $O((n + m) \times \log n + m \times \log m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别为 $heights$ 和 $queries$ 的长度。
72+
73+
相似题目:
74+
75+
- [2736. 最大和查询](/solution/2700-2799/2736.Maximum%20Sum%20Queries/README.md)
76+
6377
<!-- tabs:start -->
6478

6579
### **Python3**
6680

6781
<!-- 这里可写当前语言的特殊实现逻辑 -->
6882

6983
```python
70-
84+
class BinaryIndexedTree:
85+
__slots__ = ["n", "c"]
86+
87+
def __init__(self, n: int):
88+
self.n = n
89+
self.c = [inf] * (n + 1)
90+
91+
def update(self, x: int, v: int):
92+
while x <= self.n:
93+
self.c[x] = min(self.c[x], v)
94+
x += x & -x
95+
96+
def query(self, x: int) -> int:
97+
mi = inf
98+
while x:
99+
mi = min(mi, self.c[x])
100+
x -= x & -x
101+
return -1 if mi == inf else mi
102+
103+
104+
class Solution:
105+
def leftmostBuildingQueries(
106+
self, heights: List[int], queries: List[List[int]]
107+
) -> List[int]:
108+
n, m = len(heights), len(queries)
109+
for i in range(m):
110+
queries[i] = [min(queries[i]), max(queries[i])]
111+
j = n - 1
112+
s = sorted(set(heights))
113+
ans = [-1] * m
114+
tree = BinaryIndexedTree(n)
115+
for i in sorted(range(m), key=lambda i: -queries[i][1]):
116+
l, r = queries[i]
117+
while j > r:
118+
k = n - bisect_left(s, heights[j]) + 1
119+
tree.update(k, j)
120+
j -= 1
121+
if l == r or heights[l] < heights[r]:
122+
ans[i] = r
123+
else:
124+
k = n - bisect_left(s, heights[l])
125+
ans[i] = tree.query(k)
126+
return ans
71127
```
72128

73129
### **Java**
74130

75131
<!-- 这里可写当前语言的特殊实现逻辑 -->
76132

77133
```java
78-
134+
class BinaryIndexedTree {
135+
private final int inf = 1 << 30;
136+
private int n;
137+
private int[] c;
138+
139+
public BinaryIndexedTree(int n) {
140+
this.n = n;
141+
c = new int[n + 1];
142+
Arrays.fill(c, inf);
143+
}
144+
145+
public void update(int x, int v) {
146+
while (x <= n) {
147+
c[x] = Math.min(c[x], v);
148+
x += x & -x;
149+
}
150+
}
151+
152+
public int query(int x) {
153+
int mi = inf;
154+
while (x > 0) {
155+
mi = Math.min(mi, c[x]);
156+
x -= x & -x;
157+
}
158+
return mi == inf ? -1 : mi;
159+
}
160+
}
161+
162+
class Solution {
163+
public int[] leftmostBuildingQueries(int[] heights, int[][] queries) {
164+
int n = heights.length;
165+
int m = queries.length;
166+
for (int i = 0; i < m; ++i) {
167+
if (queries[i][0] > queries[i][1]) {
168+
queries[i] = new int[] {queries[i][1], queries[i][0]};
169+
}
170+
}
171+
Integer[] idx = new Integer[m];
172+
for (int i = 0; i < m; ++i) {
173+
idx[i] = i;
174+
}
175+
Arrays.sort(idx, (i, j) -> queries[j][1] - queries[i][1]);
176+
int[] s = heights.clone();
177+
Arrays.sort(s);
178+
int[] ans = new int[m];
179+
int j = n - 1;
180+
BinaryIndexedTree tree = new BinaryIndexedTree(n);
181+
for (int i : idx) {
182+
int l = queries[i][0], r = queries[i][1];
183+
while (j > r) {
184+
int k = n - Arrays.binarySearch(s, heights[j]) + 1;
185+
tree.update(k, j);
186+
--j;
187+
}
188+
if (l == r || heights[l] < heights[r]) {
189+
ans[i] = r;
190+
} else {
191+
int k = n - Arrays.binarySearch(s, heights[l]);
192+
ans[i] = tree.query(k);
193+
}
194+
}
195+
return ans;
196+
}
197+
}
79198
```
80199

81200
### **C++**
82201

83202
```cpp
84-
203+
class BinaryIndexedTree {
204+
private:
205+
int inf = 1 << 30;
206+
int n;
207+
vector<int> c;
208+
209+
public:
210+
BinaryIndexedTree(int n) {
211+
this->n = n;
212+
c.resize(n + 1, inf);
213+
}
214+
215+
void update(int x, int v) {
216+
while (x <= n) {
217+
c[x] = min(c[x], v);
218+
x += x & -x;
219+
}
220+
}
221+
222+
int query(int x) {
223+
int mi = inf;
224+
while (x > 0) {
225+
mi = min(mi, c[x]);
226+
x -= x & -x;
227+
}
228+
return mi == inf ? -1 : mi;
229+
}
230+
};
231+
232+
class Solution {
233+
public:
234+
vector<int> leftmostBuildingQueries(vector<int>& heights, vector<vector<int>>& queries) {
235+
int n = heights.size(), m = queries.size();
236+
for (auto& q : queries) {
237+
if (q[0] > q[1]) {
238+
swap(q[0], q[1]);
239+
}
240+
}
241+
vector<int> idx(m);
242+
iota(idx.begin(), idx.end(), 0);
243+
sort(idx.begin(), idx.end(), [&](int i, int j) {
244+
return queries[j][1] < queries[i][1];
245+
});
246+
vector<int> s = heights;
247+
sort(s.begin(), s.end());
248+
s.erase(unique(s.begin(), s.end()), s.end());
249+
vector<int> ans(m);
250+
int j = n - 1;
251+
BinaryIndexedTree tree(n);
252+
for (int i : idx) {
253+
int l = queries[i][0], r = queries[i][1];
254+
while (j > r) {
255+
int k = s.end() - lower_bound(s.begin(), s.end(), heights[j]) + 1;
256+
tree.update(k, j);
257+
--j;
258+
}
259+
if (l == r || heights[l] < heights[r]) {
260+
ans[i] = r;
261+
} else {
262+
int k = s.end() - lower_bound(s.begin(), s.end(), heights[l]);
263+
ans[i] = tree.query(k);
264+
}
265+
}
266+
return ans;
267+
}
268+
};
85269
```
86270
87271
### **Go**
88272
89273
```go
274+
const inf int = 1 << 30
275+
276+
type BinaryIndexedTree struct {
277+
n int
278+
c []int
279+
}
280+
281+
func NewBinaryIndexedTree(n int) BinaryIndexedTree {
282+
c := make([]int, n+1)
283+
for i := range c {
284+
c[i] = inf
285+
}
286+
return BinaryIndexedTree{n: n, c: c}
287+
}
288+
289+
func (bit *BinaryIndexedTree) update(x, v int) {
290+
for x <= bit.n {
291+
bit.c[x] = min(bit.c[x], v)
292+
x += x & -x
293+
}
294+
}
295+
296+
func (bit *BinaryIndexedTree) query(x int) int {
297+
mi := inf
298+
for x > 0 {
299+
mi = min(mi, bit.c[x])
300+
x -= x & -x
301+
}
302+
if mi == inf {
303+
return -1
304+
}
305+
return mi
306+
}
307+
308+
func leftmostBuildingQueries(heights []int, queries [][]int) []int {
309+
n, m := len(heights), len(queries)
310+
for _, q := range queries {
311+
if q[0] > q[1] {
312+
q[0], q[1] = q[1], q[0]
313+
}
314+
}
315+
idx := make([]int, m)
316+
for i := range idx {
317+
idx[i] = i
318+
}
319+
sort.Slice(idx, func(i, j int) bool { return queries[idx[j]][1] < queries[idx[i]][1] })
320+
s := make([]int, n)
321+
copy(s, heights)
322+
sort.Ints(s)
323+
ans := make([]int, m)
324+
tree := NewBinaryIndexedTree(n)
325+
j := n - 1
326+
for _, i := range idx {
327+
l, r := queries[i][0], queries[i][1]
328+
for ; j > r; j-- {
329+
k := n - sort.SearchInts(s, heights[j]) + 1
330+
tree.update(k, j)
331+
}
332+
if l == r || heights[l] < heights[r] {
333+
ans[i] = r
334+
} else {
335+
k := n - sort.SearchInts(s, heights[l])
336+
ans[i] = tree.query(k)
337+
}
338+
}
339+
return ans
340+
}
341+
```
90342

343+
### **TypeScript**
344+
345+
```ts
346+
class BinaryIndexedTree {
347+
private n: number;
348+
private c: number[];
349+
private inf: number = 1 << 30;
350+
351+
constructor(n: number) {
352+
this.n = n;
353+
this.c = Array(n + 1).fill(this.inf);
354+
}
355+
356+
update(x: number, v: number): void {
357+
while (x <= this.n) {
358+
this.c[x] = Math.min(this.c[x], v);
359+
x += x & -x;
360+
}
361+
}
362+
363+
query(x: number): number {
364+
let mi = this.inf;
365+
while (x > 0) {
366+
mi = Math.min(mi, this.c[x]);
367+
x -= x & -x;
368+
}
369+
return mi === this.inf ? -1 : mi;
370+
}
371+
}
372+
373+
function leftmostBuildingQueries(heights: number[], queries: number[][]): number[] {
374+
const n = heights.length;
375+
const m = queries.length;
376+
for (const q of queries) {
377+
if (q[0] > q[1]) {
378+
[q[0], q[1]] = [q[1], q[0]];
379+
}
380+
}
381+
const idx: number[] = Array(m)
382+
.fill(0)
383+
.map((_, i) => i);
384+
idx.sort((i, j) => queries[j][1] - queries[i][1]);
385+
const tree = new BinaryIndexedTree(n);
386+
const ans: number[] = Array(m).fill(-1);
387+
const s = [...heights];
388+
s.sort((a, b) => a - b);
389+
const search = (x: number) => {
390+
let [l, r] = [0, n];
391+
while (l < r) {
392+
const mid = (l + r) >> 1;
393+
if (s[mid] >= x) {
394+
r = mid;
395+
} else {
396+
l = mid + 1;
397+
}
398+
}
399+
return l;
400+
};
401+
let j = n - 1;
402+
for (const i of idx) {
403+
const [l, r] = queries[i];
404+
while (j > r) {
405+
const k = n - search(heights[j]) + 1;
406+
tree.update(k, j);
407+
--j;
408+
}
409+
if (l === r || heights[l] < heights[r]) {
410+
ans[i] = r;
411+
} else {
412+
const k = n - search(heights[l]);
413+
ans[i] = tree.query(k);
414+
}
415+
}
416+
return ans;
417+
}
91418
```
92419

93420
### **...**

0 commit comments

Comments
 (0)