题目描述
给你一个下标从 0 开始的二维整数数组 nums
表示汽车停放在数轴上的坐标。对于任意下标 i
,nums[i] = [starti, endi]
,其中 starti
是第 i
辆车的起点,endi
是第 i
辆车的终点。
返回数轴上被车 任意部分 覆盖的整数点的数目。
示例 1:
输入:nums = [[3,6],[1,5],[4,7]]
输出:7
解释:从 1 到 7 的所有点都至少与一辆车相交,因此答案为 7 。
示例 2:
输入:nums = [[1,3],[5,8]]
输出:7
解释:1、2、3、5、6、7、8 共计 7 个点满足至少与一辆车相交,因此答案为 7 。
提示:
1 <= nums.length <= 100
nums[i].length == 2
1 <= starti <= endi <= 100
解法
方法一:差分数组
根据题目描述,我们需要给每个区间 $[\textit{start}_i, \textit{end}_i]$ 增加一个车辆,我们可以使用差分数组来实现。
我们定义一个长度为 $102$ 的数组 $d$,对于每个区间 $[\textit{start}_i, \textit{end}_i]$,我们将 $d[\textit{start}_i]$ 加 $1$,将 $d[\textit{end}_i + 1]$ 减 $1$。
最后,我们对 $d$ 进行前缀和运算,统计前缀和大于 $0$ 的个数即可。
时间复杂度 $O(n + m)$,空间复杂度 $O(m)$,其中 $n$ 是给定数组的长度,而 $m$ 是数组中的最大值,本题中 $m \leq 102$。
| class Solution:
def numberOfPoints(self, nums: List[List[int]]) -> int:
m = 102
d = [0] * m
for start, end in nums:
d[start] += 1
d[end + 1] -= 1
return sum(s > 0 for s in accumulate(d))
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | class Solution {
public int numberOfPoints(List<List<Integer>> nums) {
int[] d = new int[102];
for (var e : nums) {
int start = e.get(0), end = e.get(1);
++d[start];
--d[end + 1];
}
int ans = 0, s = 0;
for (int x : d) {
s += x;
if (s > 0) {
++ans;
}
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | class Solution {
public:
int numberOfPoints(vector<vector<int>>& nums) {
int d[102]{};
for (const auto& e : nums) {
int start = e[0], end = e[1];
++d[start];
--d[end + 1];
}
int ans = 0, s = 0;
for (int x : d) {
s += x;
ans += s > 0;
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | func numberOfPoints(nums [][]int) (ans int) {
d := [102]int{}
for _, e := range nums {
start, end := e[0], e[1]
d[start]++
d[end+1]--
}
s := 0
for _, x := range d {
s += x
if s > 0 {
ans++
}
}
return
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | function numberOfPoints(nums: number[][]): number {
const d: number[] = Array(102).fill(0);
for (const [start, end] of nums) {
++d[start];
--d[end + 1];
}
let ans = 0;
let s = 0;
for (const x of d) {
s += x;
ans += s > 0 ? 1 : 0;
}
return ans;
}
|
方法二:哈希表 + 差分 + 排序
如果题目的区间范围较大,我们可以使用哈希表来存储区间的起点和终点,然后对哈希表的键进行排序,再进行前缀和统计。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为给定数组的长度。
1
2
3
4
5
6
7
8
9
10
11
12
13 | class Solution:
def numberOfPoints(self, nums: List[List[int]]) -> int:
d = defaultdict(int)
for start, end in nums:
d[start] += 1
d[end + 1] -= 1
ans = s = last = 0
for cur, v in sorted(d.items()):
if s > 0:
ans += cur - last
s += v
last = cur
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | class Solution {
public int numberOfPoints(List<List<Integer>> nums) {
TreeMap<Integer, Integer> d = new TreeMap<>();
for (var e : nums) {
int start = e.get(0), end = e.get(1);
d.merge(start, 1, Integer::sum);
d.merge(end + 1, -1, Integer::sum);
}
int ans = 0, s = 0, last = 0;
for (var e : d.entrySet()) {
int cur = e.getKey(), v = e.getValue();
if (s > 0) {
ans += cur - last;
}
s += v;
last = cur;
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | class Solution {
public:
int numberOfPoints(vector<vector<int>>& nums) {
map<int, int> d;
for (const auto& e : nums) {
int start = e[0], end = e[1];
++d[start];
--d[end + 1];
}
int ans = 0, s = 0, last = 0;
for (const auto& [cur, v] : d) {
if (s > 0) {
ans += cur - last;
}
s += v;
last = cur;
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | func numberOfPoints(nums [][]int) (ans int) {
d := map[int]int{}
for _, e := range nums {
start, end := e[0], e[1]
d[start]++
d[end+1]--
}
keys := []int{}
for k := range d {
keys = append(keys, k)
}
s, last := 0, 0
sort.Ints(keys)
for _, cur := range keys {
if s > 0 {
ans += cur - last
}
s += d[cur]
last = cur
}
return
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | function numberOfPoints(nums: number[][]): number {
const d = new Map<number, number>();
for (const [start, end] of nums) {
d.set(start, (d.get(start) || 0) + 1);
d.set(end + 1, (d.get(end + 1) || 0) - 1);
}
const keys = [...d.keys()].sort((a, b) => a - b);
let [ans, s, last] = [0, 0, 0];
for (const cur of keys) {
if (s > 0) {
ans += cur - last;
}
s += d.get(cur)!;
last = cur;
}
return ans;
}
|