Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f83fc91

Browse files
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‎

Lines changed: 4 additions & 0 deletions
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‎

Lines changed: 4 additions & 0 deletions
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‎

Lines changed: 330 additions & 3 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /