Skip to content

Commit 1b5cb55

Browse files
authored
feat: add biweekly contest 174 (#4974)
1 parent 17c585f commit 1b5cb55

38 files changed

Lines changed: 2383 additions & 3 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
- [乘积小于 K 的子数组](/solution/0700-0799/0713.Subarray%20Product%20Less%20Than%20K/README.md) - `双指针`
5353
- [位 1 的个数](/solution/0100-0199/0191.Number%20of%201%20Bits/README.md) - `位运算``lowbit`
5454
- [合并区间](/solution/0000-0099/0056.Merge%20Intervals/README.md) - `区间合并`
55-
<!-- 排序算法、待补充 -->
55+
<!-- 排序算法、待补充 -->
5656

5757
### 2. 数据结构
5858

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
---
2+
comments: true
3+
difficulty: 中等
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3809.Best%20Reachable%20Tower/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3809. 最好可到达的塔](https://leetcode.cn/problems/best-reachable-tower)
10+
11+
[English Version](/solution/3800-3899/3809.Best%20Reachable%20Tower/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>给你一个二维整数数组 <code>towers</code>,其中 <code>towers[i] = [x<sub>i</sub>, y<sub>i</sub>, q<sub>i</sub>]</code> 表示第 <code>i</code> 座塔的坐标 <code>(x<sub>i</sub>, y<sub>i</sub>)</code> 和质量因子 <code>q<sub>i</sub></code>。</p>
18+
19+
<p>另外给你一个整数数组 <code>center = [cx, cy]</code> 表示你的位置,以及一个整数 <code>radius</code>。</p>
20+
21+
<p>如果一座塔与 <code>center</code> 之间的 <strong>曼哈顿距离</strong><strong>小于或等于</strong> <code>radius</code>,则称该塔是 <strong>可到达的</strong>。</p>
22+
23+
<p>在所有可到达的塔中:</p>
24+
25+
<ul>
26+
<li>返回质量因子 <strong>最大</strong> 的塔的坐标。</li>
27+
<li>如果存在并列的塔,返回坐标 <strong>字典序最小</strong> 的塔。如果没有塔是可到达的,返回 <code>[-1, -1]</code>。</li>
28+
</ul>
29+
两点 <code>(x<sub>i</sub>, y<sub>i</sub>)</code> 和 <code>(x<sub>j</sub>, y<sub>j</sub>)</code> 之间的 <strong>曼哈顿距离</strong> 为 <code>|x<sub>i</sub> - x<sub>j</sub>| + |y<sub>i</sub> - y<sub>j</sub>|</code>。
30+
31+
<p>坐标 <code>[x<sub>i</sub>, y<sub>i</sub>]</code> <strong>字典序小于</strong> <code>[x<sub>j</sub>, y<sub>j</sub>]</code> 是指:<code>x<sub>i</sub> &lt; x<sub>j</sub></code>,或者 <code>x<sub>i</sub> == x<sub>j</sub></code> 且 <code>y<sub>i</sub> &lt; y<sub>j</sub></code>。</p>
32+
33+
<p><code>|x|</code> 表示 <code>x</code> 的 <strong>绝对值</strong>。</p>
34+
35+
<p>&nbsp;</p>
36+
37+
<p><strong class="example">示例 1:</strong></p>
38+
39+
<div class="example-block">
40+
<p><strong>输入:</strong> <span class="example-io">towers = [[1,2,5], [2,1,7], [3,1,9]], center = [1,1], radius = 2</span></p>
41+
42+
<p><strong>输出:</strong> <span class="example-io">[3,1]</span></p>
43+
44+
<p><strong>解释:</strong></p>
45+
46+
<ul>
47+
<li>塔 <code>[1, 2, 5]</code>:曼哈顿距离 = <code>|1 - 1| + |2 - 1| = 1</code>,可到达。</li>
48+
<li>塔 <code>[2, 1, 7]</code>:曼哈顿距离 = <code>|2 - 1| + |1 - 1| = 1</code>,可到达。</li>
49+
<li>塔 <code>[3, 1, 9]</code>:曼哈顿距离 = <code>|3 - 1| + |1 - 1| = 2</code>,可到达。</li>
50+
</ul>
51+
52+
<p>所有塔都是可到达的。最大质量因子为 9,对应塔 <code>[3, 1]</code>。</p>
53+
</div>
54+
55+
<p><strong class="example">示例 2:</strong></p>
56+
57+
<div class="example-block">
58+
<p><strong>输入:</strong> <span class="example-io">towers = [[1,3,4], [2,2,4], [4,4,7]], center = [0,0], radius = 5</span></p>
59+
60+
<p><strong>输出:</strong> <span class="example-io">[1,3]</span></p>
61+
62+
<p><strong>解释:</strong></p>
63+
64+
<ul>
65+
<li>塔 <code>[1, 3, 4]</code>:曼哈顿距离 = <code>|1 - 0| + |3 - 0| = 4</code>,可到达。</li>
66+
<li>塔 <code>[2, 2, 4]</code>:曼哈顿距离 = <code>|2 - 0| + |2 - 0| = 4</code>,可到达。</li>
67+
<li>塔 <code>[4, 4, 7]</code>:曼哈顿距离 = <code>|4 - 0| + |4 - 0| = 8</code>,不可到达。</li>
68+
</ul>
69+
70+
<p>在可到达的塔中,最大质量因子为 4。<code>[1, 3]</code> 和 <code>[2, 2]</code> 的质量因子相同,因此返回字典序较小的坐标 <code>[1, 3]</code>。</p>
71+
</div>
72+
73+
<p><strong class="example">示例 3:</strong></p>
74+
75+
<div class="example-block">
76+
<p><strong>输入:</strong> <span class="example-io">towers = [[5,6,8], [0,3,5]], center = [1,2], radius = 1</span></p>
77+
78+
<p><strong>输出:</strong> <span class="example-io">[-1,-1]</span></p>
79+
80+
<p><strong>解释:</strong></p>
81+
82+
<ul>
83+
<li>塔 <code>[5, 6, 8]</code>:曼哈顿距离 = <code>|5 - 1| + |6 - 2| = 8</code>,不可到达。</li>
84+
<li>塔 <code>[0, 3, 5]</code>:曼哈顿距离 = <code>|0 - 1| + |3 - 2| = 2</code>,不可到达。</li>
85+
</ul>
86+
87+
<p>在给定半径内没有可到达的塔,故返回 <code>[-1, -1]</code>。</p>
88+
</div>
89+
90+
<p>&nbsp;</p>
91+
92+
<p><strong>提示:</strong></p>
93+
94+
<ul>
95+
<li><code>1 &lt;= towers.length &lt;= 10<sup>5</sup></code></li>
96+
<li><code>towers[i] = [x<sub>i</sub>, y<sub>i</sub>, q<sub>i</sub>]</code></li>
97+
<li><code>center = [cx, cy]</code></li>
98+
<li><code>0 &lt;= x<sub>i</sub>, y<sub>i</sub>, q<sub>i</sub>, cx, cy &lt;= 10<sup>5</sup></code></li>
99+
<li><code>0 &lt;= radius &lt;= 10<sup>5</sup></code></li>
100+
</ul>
101+
102+
<!-- description:end -->
103+
104+
## 解法
105+
106+
<!-- solution:start -->
107+
108+
### 方法一:一次遍历
109+
110+
我们定义一个变量 $\textit{idx}$ 来记录当前最佳塔的下标,初始时 $\textit{idx} = -1$。然后我们遍历每一座塔,计算其与 $\textit{center}$ 之间的曼哈顿距离 $\textit{dist}$:
111+
112+
$$
113+
\textit{dist} = |x_i - cx| + |y_i - cy|
114+
$$
115+
116+
如果 $\textit{dist} > \textit{radius}$,则该塔不可到达,跳过该塔。否则,我们比较当前塔与最佳塔的质量因子 $q$:
117+
118+
- 如果 $\textit{idx} = -1$,说明当前还没有可到达的塔,我们将 $\textit{idx}$ 更新为当前塔的下标。
119+
- 如果当前塔的质量因子 $q_i$ 大于最佳塔的质量因子 $q_{\textit{idx}}$,则将 $\textit{idx}$ 更新为当前塔的下标。
120+
- 如果当前塔的质量因子 $q_i$ 等于最佳塔的质量因子 $q_{\textit{idx}}$,则比较两座塔的坐标,选择字典序较小的塔。
121+
122+
遍历结束后,如果 $\textit{idx} = -1$,说明没有可到达的塔,返回 $[-1, -1]$。否则,返回最佳塔的坐标。
123+
124+
时间复杂度 $O(n)$,其中 $n$ 是塔的数量。空间复杂度 $O(1)$。
125+
126+
<!-- tabs:start -->
127+
128+
#### Python3
129+
130+
```python
131+
class Solution:
132+
def bestTower(
133+
self, towers: List[List[int]], center: List[int], radius: int
134+
) -> List[int]:
135+
cx, cy = center
136+
idx = -1
137+
for i, (x, y, q) in enumerate(towers):
138+
dist = abs(x - cx) + abs(y - cy)
139+
if dist > radius:
140+
continue
141+
if (
142+
idx == -1
143+
or towers[idx][2] < q
144+
or (towers[idx][2] == q and towers[i][:2] < towers[idx][:2])
145+
):
146+
idx = i
147+
return [-1, -1] if idx == -1 else towers[idx][:2]
148+
```
149+
150+
#### Java
151+
152+
```java
153+
class Solution {
154+
public int[] bestTower(int[][] towers, int[] center, int radius) {
155+
int cx = center[0], cy = center[1];
156+
int idx = -1;
157+
for (int i = 0; i < towers.length; i++) {
158+
int x = towers[i][0], y = towers[i][1], q = towers[i][2];
159+
int dist = Math.abs(x - cx) + Math.abs(y - cy);
160+
if (dist > radius) {
161+
continue;
162+
}
163+
if (idx == -1 || towers[idx][2] < q
164+
|| (towers[idx][2] == q
165+
&& (x < towers[idx][0] || (x == towers[idx][0] && y < towers[idx][1])))) {
166+
idx = i;
167+
}
168+
}
169+
return idx == -1 ? new int[] {-1, -1} : new int[] {towers[idx][0], towers[idx][1]};
170+
}
171+
}
172+
```
173+
174+
#### C++
175+
176+
```cpp
177+
class Solution {
178+
public:
179+
vector<int> bestTower(vector<vector<int>>& towers, vector<int>& center, int radius) {
180+
int cx = center[0], cy = center[1];
181+
int idx = -1;
182+
for (int i = 0; i < towers.size(); ++i) {
183+
int x = towers[i][0], y = towers[i][1], q = towers[i][2];
184+
int dist = abs(x - cx) + abs(y - cy);
185+
if (dist > radius) {
186+
continue;
187+
}
188+
if (
189+
idx == -1
190+
|| towers[idx][2] < q
191+
|| (towers[idx][2] == q && (x < towers[idx][0] || (x == towers[idx][0] && y < towers[idx][1])))) {
192+
idx = i;
193+
}
194+
}
195+
if (idx == -1) {
196+
return {-1, -1};
197+
}
198+
return {towers[idx][0], towers[idx][1]};
199+
}
200+
};
201+
```
202+
203+
#### Go
204+
205+
```go
206+
func bestTower(towers [][]int, center []int, radius int) []int {
207+
cx, cy := center[0], center[1]
208+
idx := -1
209+
for i, a := range towers {
210+
x, y, q := a[0], a[1], a[2]
211+
dist := abs(x-cx) + abs(y-cy)
212+
if dist > radius {
213+
continue
214+
}
215+
if idx == -1 ||
216+
towers[idx][2] < q ||
217+
(towers[idx][2] == q &&
218+
(x < towers[idx][0] ||
219+
(x == towers[idx][0] && y < towers[idx][1]))) {
220+
idx = i
221+
}
222+
}
223+
if idx == -1 {
224+
return []int{-1, -1}
225+
}
226+
return []int{towers[idx][0], towers[idx][1]}
227+
}
228+
229+
func abs(x int) int {
230+
if x < 0 {
231+
return -x
232+
}
233+
return x
234+
}
235+
```
236+
237+
#### TypeScript
238+
239+
```ts
240+
function bestTower(towers: number[][], center: number[], radius: number): number[] {
241+
const [cx, cy] = center;
242+
let idx = -1;
243+
for (let i = 0; i < towers.length; i++) {
244+
const [x, y, q] = towers[i];
245+
const dist = Math.abs(x - cx) + Math.abs(y - cy);
246+
if (dist > radius) {
247+
continue;
248+
}
249+
if (
250+
idx === -1 ||
251+
towers[idx][2] < q ||
252+
(towers[idx][2] === q &&
253+
(x < towers[idx][0] || (x === towers[idx][0] && y < towers[idx][1])))
254+
) {
255+
idx = i;
256+
}
257+
}
258+
return idx === -1 ? [-1, -1] : [towers[idx][0], towers[idx][1]];
259+
}
260+
```
261+
262+
<!-- tabs:end -->
263+
264+
<!-- solution:end -->
265+
266+
<!-- problem:end -->

0 commit comments

Comments
 (0)