算法题-网络信号最好的坐标

204 阅读2分钟

LeetCode:网络信号最好的坐标

给你一个数组 towers 和一个整数 radius 。

数组  towers  中包含一些网络信号塔,其中 towers[i] = [xi, yi, qi] 表示第 i 个网络信号塔的坐标是 (xi, yi) 且信号强度参数为 qi 。所有坐标都是在  X-Y 坐标系内的 整数 坐标。两个坐标之间的距离用 欧几里得距离 计算。

整数 radius 表示一个塔 能到达 的 最远距离 。如果一个坐标跟塔的距离在 radius 以内,那么该塔的信号可以到达该坐标。在这个范围以外信号会很微弱,所以 radius 以外的距离该塔是 不能到达的 。

如果第 i 个塔能到达 (x, y) ,那么该塔在此处的信号为 ⌊qi / (1 + d)⌋ ,其中 d 是塔跟此坐标的距离。一个坐标的 信号强度 是所有 能到达 该坐标的塔的信号强度之和。

请你返回数组 [cx, cy] ,表示 信号强度 最大的 整数 坐标点 (cx, cy) 。如果有多个坐标网络信号一样大,请你返回字典序最小的 非负 坐标。

注意:

  • 坐标 (x1, y1) 字典序比另一个坐标 (x2, y2) 小,需满足以下条件之一:

    • 要么 x1 < x2 ,
    • 要么 x1 == x2 且 y1 < y2 。
  • ⌊val⌋ 表示小于等于 val 的最大整数(向下取整函数)。

示例 1:

输入: towers = [[23,11,21]], radius = 9
输出: [23,11]
解释: 由于仅存在一座信号塔,所以塔的位置信号强度最大。

示例 2:

输入: towers = [[1,2,13],[2,1,7],[0,1,9]], radius = 2
输出: [1,2]
解释: 坐标 (1, 2) 的信号强度最大。

提示:

  • 1 <= towers.length <= 50
  • towers[i].length == 3
  • 0 <= xi, yi, qi <= 50
  • 1 <= radius <= 50

解题思路

根据题目数据范围,且题目要我们求非负坐标(也就是第一象限内及xy轴上的点)。可以知道所能到达的最远点是边长为100的正方形区域(即x=0,x=100,y=0,y=100围成的区域),但注意:并不是该正方形内的所有整数坐标均能到达!!!这一点在代码中有体现!

定义一个能覆盖所以区域点的二维数组res。 res[i][j]:当前位置所接收到的信号强度总和 遍历每个塔,将在该塔覆盖的范围内的点所在处接收到该塔的信号强度求出。那么最后就可得到某个位置处的信号强度之和! 求出信号强度最大处的坐标且其符合字典序最小!

解题代码

public int[] bestCoordinate(int[][] towers, int radius) {
    int[][] res = new int[101][101];
    int[] index = new int[2];
    int max = 0;
    //遍历每个塔
    for (int i = 0; i < towers.length; i++) {
        int x = towers[i][0];
        int y = towers[i][1];
        int q = towers[i][2];
        //遍历当前塔所能覆盖到的所有整数坐标
        for (int j = x - radius; j <= x + radius; j++) {
            for (int k = y - radius; k <= y + radius; k++) {
                //保证是第一象限的坐标
                if (j >= 0 && k >= 0) {
                    double d = Math.sqrt((j - x) * (j - x) + (k - y) * (k - y));
                    //这句代码目的就是为了将在方形区域内但不在以该塔坐标为中心点的圆域内的点排除!
                    if (d > radius) continue;
                    res[j][k] += Math.floor(q / (1 + d));
                }
            }
        }
    }
    //遍历所有能到达的点,找出信号强度最大的点且满足是字典序最小
    for (int i = 0; i < 101; i++) {
        for (int j = 0; j < 101; j++) {
            if (max < res[i][j]) {
                max = res[i][j];
                index[0] = i;
                index[1] = j;
            } else if (max == res[i][j] && (i < index[0]) || (i == index[0] && j < index[1])) {
                index[0] = i;
                index[1] = j;
            }
        }
    }
    return index;
}

运行结果

Snipaste_2023-06-25_23-27-52.png

复杂度详情

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!