跳转至

3809. 最好可到达的塔

题目描述

给你一个二维整数数组 towers,其中 towers[i] = [xi, yi, qi] 表示第 i 座塔的坐标 (xi, yi) 和质量因子 qi

另外给你一个整数数组 center = [cx, cy] 表示你的位置,以及一个整数 radius

如果一座塔与 center 之间的 曼哈顿距离小于或等于 radius,则称该塔是 可到达的

在所有可到达的塔中:

  • 返回质量因子 最大 的塔的坐标。
  • 如果存在并列的塔,返回坐标 字典序最小 的塔。如果没有塔是可到达的,返回 [-1, -1]

两点 (xi, yi)(xj, yj) 之间的 曼哈顿距离|xi - xj| + |yi - yj|

坐标 [xi, yi] 字典序小于 [xj, yj] 是指:xi < xj,或者 xi == xjyi < yj

|x| 表示 x绝对值

 

示例 1:

输入: towers = [[1,2,5], [2,1,7], [3,1,9]], center = [1,1], radius = 2

输出: [3,1]

解释:

  • [1, 2, 5]:曼哈顿距离 = |1 - 1| + |2 - 1| = 1,可到达。
  • [2, 1, 7]:曼哈顿距离 = |2 - 1| + |1 - 1| = 1,可到达。
  • [3, 1, 9]:曼哈顿距离 = |3 - 1| + |1 - 1| = 2,可到达。

所有塔都是可到达的。最大质量因子为 9,对应塔 [3, 1]

示例 2:

输入: towers = [[1,3,4], [2,2,4], [4,4,7]], center = [0,0], radius = 5

输出: [1,3]

解释:

  • [1, 3, 4]:曼哈顿距离 = |1 - 0| + |3 - 0| = 4,可到达。
  • [2, 2, 4]:曼哈顿距离 = |2 - 0| + |2 - 0| = 4,可到达。
  • [4, 4, 7]:曼哈顿距离 = |4 - 0| + |4 - 0| = 8,不可到达。

在可到达的塔中,最大质量因子为 4。[1, 3][2, 2] 的质量因子相同,因此返回字典序较小的坐标 [1, 3]

示例 3:

输入: towers = [[5,6,8], [0,3,5]], center = [1,2], radius = 1

输出: [-1,-1]

解释:

  • [5, 6, 8]:曼哈顿距离 = |5 - 1| + |6 - 2| = 8,不可到达。
  • [0, 3, 5]:曼哈顿距离 = |0 - 1| + |3 - 2| = 2,不可到达。

在给定半径内没有可到达的塔,故返回 [-1, -1]

 

提示:

  • 1 <= towers.length <= 105
  • towers[i] = [xi, yi, qi]
  • center = [cx, cy]
  • 0 <= xi, yi, qi, cx, cy <= 105
  • 0 <= radius <= 105

解法

方法一:一次遍历

我们定义一个变量 \(\textit{idx}\) 来记录当前最佳塔的下标,初始时 \(\textit{idx} = -1\)。然后我们遍历每一座塔,计算其与 \(\textit{center}\) 之间的曼哈顿距离 \(\textit{dist}\)

\[ \textit{dist} = |x_i - cx| + |y_i - cy| \]

如果 \(\textit{dist} > \textit{radius}\),则该塔不可到达,跳过该塔。否则,我们比较当前塔与最佳塔的质量因子 \(q\)

  • 如果 \(\textit{idx} = -1\),说明当前还没有可到达的塔,我们将 \(\textit{idx}\) 更新为当前塔的下标。
  • 如果当前塔的质量因子 \(q_i\) 大于最佳塔的质量因子 \(q_{\textit{idx}}\),则将 \(\textit{idx}\) 更新为当前塔的下标。
  • 如果当前塔的质量因子 \(q_i\) 等于最佳塔的质量因子 \(q_{\textit{idx}}\),则比较两座塔的坐标,选择字典序较小的塔。

遍历结束后,如果 \(\textit{idx} = -1\),说明没有可到达的塔,返回 \([-1, -1]\)。否则,返回最佳塔的坐标。

时间复杂度 \(O(n)\),其中 \(n\) 是塔的数量。空间复杂度 \(O(1)\)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution:
    def bestTower(
        self, towers: List[List[int]], center: List[int], radius: int
    ) -> List[int]:
        cx, cy = center
        idx = -1
        for i, (x, y, q) in enumerate(towers):
            dist = abs(x - cx) + abs(y - cy)
            if dist > radius:
                continue
            if (
                idx == -1
                or towers[idx][2] < q
                or (towers[idx][2] == q and towers[i][:2] < towers[idx][:2])
            ):
                idx = i
        return [-1, -1] if idx == -1 else towers[idx][:2]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution {
    public int[] bestTower(int[][] towers, int[] center, int radius) {
        int cx = center[0], cy = center[1];
        int idx = -1;
        for (int i = 0; i < towers.length; i++) {
            int x = towers[i][0], y = towers[i][1], q = towers[i][2];
            int dist = Math.abs(x - cx) + Math.abs(y - cy);
            if (dist > radius) {
                continue;
            }
            if (idx == -1 || towers[idx][2] < q
                || (towers[idx][2] == q
                    && (x < towers[idx][0] || (x == towers[idx][0] && y < towers[idx][1])))) {
                idx = i;
            }
        }
        return idx == -1 ? new int[] {-1, -1} : new int[] {towers[idx][0], towers[idx][1]};
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
    vector<int> bestTower(vector<vector<int>>& towers, vector<int>& center, int radius) {
        int cx = center[0], cy = center[1];
        int idx = -1;
        for (int i = 0; i < towers.size(); ++i) {
            int x = towers[i][0], y = towers[i][1], q = towers[i][2];
            int dist = abs(x - cx) + abs(y - cy);
            if (dist > radius) {
                continue;
            }
            if (
                idx == -1
                || towers[idx][2] < q
                || (towers[idx][2] == q && (x < towers[idx][0] || (x == towers[idx][0] && y < towers[idx][1])))) {
                idx = i;
            }
        }
        if (idx == -1) {
            return {-1, -1};
        }
        return {towers[idx][0], towers[idx][1]};
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func bestTower(towers [][]int, center []int, radius int) []int {
    cx, cy := center[0], center[1]
    idx := -1
    for i, a := range towers {
        x, y, q := a[0], a[1], a[2]
        dist := abs(x-cx) + abs(y-cy)
        if dist > radius {
            continue
        }
        if idx == -1 ||
            towers[idx][2] < q ||
            (towers[idx][2] == q &&
                (x < towers[idx][0] ||
                    (x == towers[idx][0] && y < towers[idx][1]))) {
            idx = i
        }
    }
    if idx == -1 {
        return []int{-1, -1}
    }
    return []int{towers[idx][0], towers[idx][1]}
}

func abs(x int) int {
    if x < 0 {
        return -x
    }
    return x
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
function bestTower(towers: number[][], center: number[], radius: number): number[] {
    const [cx, cy] = center;
    let idx = -1;
    for (let i = 0; i < towers.length; i++) {
        const [x, y, q] = towers[i];
        const dist = Math.abs(x - cx) + Math.abs(y - cy);
        if (dist > radius) {
            continue;
        }
        if (
            idx === -1 ||
            towers[idx][2] < q ||
            (towers[idx][2] === q &&
                (x < towers[idx][0] || (x === towers[idx][0] && y < towers[idx][1])))
        ) {
            idx = i;
        }
    }
    return idx === -1 ? [-1, -1] : [towers[idx][0], towers[idx][1]];
}

评论