一条街上有很多的路灯,路灯的坐标由数组 lights
的形式给出。 每个 lights[i] = [positioni, rangei]
代表坐标为 positioni
的路灯照亮的范围为 [positioni - rangei, positioni + rangei]
(包括顶点)。
位置 p
的亮度由能够照到 p
的路灯的数量来决定的。
给出 lights
, 返回最亮的位置 。如果有很多,返回坐标最小的。
示例 1:
输入: lights = [[-3,2],[1,2],[3,3]] 输出: -1 解释: 第一个路灯照亮的范围是[(-3) - 2, (-3) + 2] = [-5, -1]. 第二个路灯照亮的范围是 [1 - 2, 1 + 2] = [-1, 3]. 第三个路灯照亮的范围是 [3 - 3, 3 + 3] = [0, 6]. 坐标-1被第一个和第二个路灯照亮,亮度为2 坐标0,1,2都被第二个和第三个路灯照亮,亮度为2. 对于以上坐标,-1最小,所以返回-1
示例 2:
输入: lights = [[1,0],[0,1]] 输出: 1
示例 3:
输入: lights = [[1,2]] 输出: -1
提示:
1 <= lights.length <= 10^5
lights[i].length == 2
-10^8 <= positioni <= 10^8
0 <= rangei <= 10^8
提示 1
Convert lights into an array of ranges representing the range where each street light can light up and sort the start and end points of the ranges.
提示 2
Do we need to traverse all possible positions on the street?
提示 3
No, we don't, we only need to go to the start and end points of the ranges for each streetlight.
解法1:线性扫描 + 差分 + 排序
Java版:
class Solution {
public int brightestPosition(int[][] lights) {
List<int[]> points = new ArrayList<>();
for (int[] light: lights) {
points.add(new int[]{light[0] - light[1], 1});
points.add(new int[]{light[0] + light[1] + 1, -1});
}
Collections.sort(points, new Comparator<int[]>() {
public int compare(int[] p1, int[] p2) {
return p1[0] != p2[0] ? p1[0] - p2[0] : p1[1] - p2[1];
}
});
int maxlight = 0;
int ans = 0;
int light = 0;
for (int[] point: points) {
light += point[1];
if (light > maxlight) {
maxlight = light;
ans = point[0];
}
}
return ans;
}
}
Python3版:
class Solution:
def brightestPosition(self, lights: List[List[int]]) -> int:
points = []
for p, r in lights:
points.append([p - r, 1])
points.append([p + r + 1, -1])
points.sort()
light = 0
maxlight = 0
ans = 0
for p, c in points:
light += c
if light > maxlight:
maxlight = light
ans = p
return ans
复杂度分析
-
时间复杂度:O(M+NlogN),其中 M,N 分别是数组 lights 和 points 的长度。
-
空间复杂度:O(N),其中 N 是数组 points 的长度。