与车相交的点

标签: 数组 哈希表 前缀和

难度: Easy

给你一个下标从 0 开始的二维整数数组 nums 表示汽车停放在数轴上的坐标。对于任意下标 inums[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

Submission

运行时间: 28 ms

内存: 16.1 MB

class Solution:
    def numberOfPoints(self, nums: List[List[int]]) -> int:
        nums = list(sorted(nums))
        m = nums[0]
        ans = 0
        for i in range(1, len(nums)):
            if nums[i][0] <= m[1]:
                m = [m[0], max(m[1], nums[i][1])]
            else:
                ans += m[1] - m[0] + 1
                m = nums[i]
        ans += m[1] - m[0] + 1
        return ans

Explain

此题解采用了区间合并的策略来计算被至少一辆车覆盖的整数点的总数。首先,对输入的区间数组nums进行排序,以保证区间的起点是递增的。然后,使用一个变量m来维护当前正在合并的区间。遍历排序后的数组,对于每个区间,如果它的起点在当前合并区间m的终点之前或恰好相等,则将其与m进行合并,即更新m的终点为当前区间终点和m终点的较大者。如果新区间的起点在m的终点之后,说明没有重叠部分,当前m区间的计算可以结束,并将其长度加到答案中,然后用新区间更新m。遍历结束后,将最后一个区间的长度也加到答案中。

时间复杂度: O(n log n)

空间复杂度: O(n)

class Solution:
    def numberOfPoints(self, nums: List[List[int]]) -> int:
        nums = list(sorted(nums))  # 对车辆区间进行排序
        m = nums[0]  # 初始化当前合并的区间为第一个区间
        ans = 0  # 初始化结果变量
        for i in range(1, len(nums)):
            if nums[i][0] <= m[1]:
                m = [m[0], max(m[1], nums[i][1])]  # 合并区间
            else:
                ans += m[1] - m[0] + 1  # 计算没有重叠部分的区间长度,并加到结果中
                m = nums[i]  # 更新当前区间
        ans += m[1] - m[0] + 1  # 加上最后一个区间的长度
        return ans  # 返回结果

Explore

在题解中,区间的排序是基于区间的起点进行的。这样做的目的是为了方便后续的区间合并操作,因为一旦区间按起点排序,只需要关注当前区间的终点和下一个区间的起点的关系即可轻松决定是否进行合并。如果按终点排序,则在处理重叠区间时会更复杂,因为可能需要回溯合并已经检查过的区间。

是的,题解中的合并区间方法考虑了所有可能的重叠和非重叠场景。如果有多个区间完全重叠,即它们的起点和终点完全相同或者某个区间完全包含于另一个区间内,合并逻辑仍然适用。在这种情况下,合并操作将维护一个当前正在合并的区间,其终点是所有重叠区间的最远终点,因此完全重叠的区间会被合并为一个区间,而不会重复计算。

在处理完所有区间后,需要再单独添加最后一个区间的长度,是因为在遍历区间的过程中,每次合并完成后只记录了非重叠部分的长度。最后一个区间在退出循环时没有后续区间与之比较和合并,因此其长度没有被加入到最终的计算结果中。所以,我们需要在循环结束后,将最后一个区间的长度也加入到总长度中。这并不是重复计算,而是确保所有合并或单独的区间都被正确计算。

当前的方法在理论上对于非常大的数据仍然适用,因为它主要依赖于排序和遍历,其时间复杂度主要是O(n log n),其中n是区间的数量。但是,如果区间的数量极大或区间的范围非常广,我们可能需要考虑内存使用和处理时间的优化。一种可能的优化是使用更高效的数据结构,例如平衡二叉搜索树(如AVL树或红黑树),来动态管理合并的区间,这可以在一定程度上减少排序和合并的开销。此外,对于特别大的数据,考虑使用并行处理或分布式处理的方法来加速处理过程也是必要的。