2848. 与车相交的点 Points That Intersect With Cars
这个问题的解法就比较多了.
哈稀表
确切来说是 HashSet, 我们用集合来统计每辆车占用的点位, 最后计算集合中点的个数就行.
操作步骤如下:
- 创建统计用的集合
- 遍历所有车辆, 将每个车辆占用的点位区间上的所有点, 都加入到集合中
- 集合的长度就是所有的点位数
#![allow(unused)] fn main() { // Hash Map pub fn number_of_points1(nums: Vec<Vec<i32>>) -> i32 { debug_assert!(!nums.is_empty()); let mut set = HashSet::new(); for num in nums { debug_assert!(num.len() == 2); for i in num[0]..=num[1] { set.insert(i); } } set.len() as i32 } }
该算法的时间复杂度是 O(n)
, 空间复杂度是 O(n)
.
Bitset
这个是对上述方法的优化, 因为给定的点数比较少, 我们也可以直接使用 Bitset 来统计点位数,
为了实现简单, 我们直接使用 [false; 101]
来作为 bitset.
#![allow(unused)] fn main() { // Bit Set pub fn number_of_points2(nums: Vec<Vec<i32>>) -> i32 { debug_assert!(!nums.is_empty()); let mut bitset = vec![false; 101]; for num in nums { for i in num[0]..=num[1] { debug_assert!(i >= 0); bitset[i as usize] = true; } } bitset.into_iter().filter(|x| *x).count() as i32 } }
该算法的时间复杂度是 O(n)
, 空间复杂度是 O(n)
.
合并区间 Merge intervals
这个方法是 0056. Merge intervals 的解法.
因为给定的区间是无序的, 我们先以每个区间的起始点来对它进行排序, 之后再统计.
步骤如下:
- 对所有车辆所占用的区间的起始点进行排序
- 创建一个动态数组
intervals
, 用来存储不重叠的区间 - 遍历
nums
中的所有数对, 然后合并有重叠的区间, 并将不重叠的区间存储到intervals
数组中- 如果有重叠, 只需要更新区间的终点值即可
- 如果没有重叠, 则需要把之间的区间存到
intervals
数组, 并同时更新起点和重点
- 遍历
intervals
数组, 统计所有不重叠区间占用的点数
#![allow(unused)] fn main() { // Merge Intervals // See leetcode #0056 pub fn number_of_points4(nums: Vec<Vec<i32>>) -> i32 { debug_assert!(!nums.is_empty()); // 先对间隔的起始点排序 let mut nums = nums; nums.sort_unstable_by_key(|num| num[0]); let mut intervals = Vec::with_capacity(nums.len()); let mut start = nums[0][0]; let mut end = nums[0][1]; for num in nums.into_iter().skip(1) { if num[0] > end { // 说明有间隔, 要移动起始点和终点 intervals.push((start, end)); start = num[0]; end = num[1]; } else { // 没有间隔, 只移动终点 end = end.max(num[1]); } } // 最后一个间隔值 intervals.push((start, end)); let mut count = 0; for (start, end) in intervals { count += end - start + 1; } count } }
该算法的时间复杂度是 O(n log(n))
, 空间复杂度是 O(n)
.