高级农民
- 积分
- 4020
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2017-1-22
- 最后登录
- 1970-1-1
|
LC 3323. Minimize Connected Groups by Inserting Interval
You are given a 2D array intervals, where intervals[i] = [starti, endi] represents the start and the end of interval i. You are also given an integer k.
You must add exactly one new interval [startnew, endnew] to the array such that:
The length of the new interval, endnew - startnew, is at most k.
After adding, the number of connected groups in intervals is minimized.
A connected group of intervals is a maximal collection of intervals that, when considered together, cover a continuous range from the smallest point to the largest point with no gaps between them. Here are some examples:
A group of intervals [[1, 2], [2, 5], [3, 3]] is connected because together they cover the range from 1 to 5 without any gaps.
However, a group of intervals [[1, 2], [3, 4]] is not connected because the segment (2, 3) is not covered.
Return the minimum number of connected groups after adding exactly one new interval to the array.
Example 1:
Input: intervals = [[1,3],[5,6],[8,10]], k = 3
Output: 2
Explanation:
After adding the interval [3, 5], we have two connected groups: [[1, 3], [3, 5], [5, 6]] and [[8, 10]].
Example 2:
Input: intervals = [[5,10],[1,1],[3,3]], k = 1
Output: 3
Explanation:
After adding the interval [1, 1], we have three connected groups: [[1, 1], [1, 1]], [[3, 3]], and [[5, 10]].
Constraints:
1 <= intervals.length <= 105
intervals[i] == [starti, endi]
1 <= starti <= endi <= 109
1 <= k <= 109 - class Solution:
- def minConnectedGroups(self, intervals: List[List[int]], k: int) -> int:
- # sort intervals
- intervals = sorted(intervals, key = lambda x: x[0])
- # merge all existing connected intervals since they do not need to be connected
- merged = []
- for interval in intervals:
- if not merged or interval[0] > merged[-1][1]:
- # safe to add, not merged --> empty list at begining, and gapped intervals
- merged.append(interval)
- else:
- # merge connected intervals
- merged[-1][1] = max(merged[-1][1], interval[1])
-
- # check intervals can be linked by k
- ans = len(merged) # worset case no new connecte groups, like gap too wide
- n = len(merged)
- l = 0
- r = l + 1
-
- while l < n:
- while r < n and (merged[r][0] - merged[l][1] <= k):
- ans = min(ans, n - (r-l))
- r += 1
- l += 1
- return ans
复制代码 原始代码超时, TLE, 因为内部两层嵌套,- while l < n:
- r = l + 1
- while r < n and (merged[r][0] - merged[l][1] <= k):
- ans = min(ans, n - (r - l)) # 这里的 r 每次都从 l+1 开始重扫
- r += 1
- l += 1
复制代码即使你的逻辑对,但如果 $k$ 很大,内部的 while r < n 可能会运行成千上万次。对于每一个 l,你都让 r 重新出发,这在计算机看来太累了。优化方案:滑动窗口 (Sliding Window)其实 r 并不需要每次都回到 l + 1。由于 merged 数组已经是按顺序排好的,当 l 向右移动时,merged[l][1] 也会变大。这意味着原本能被 l 覆盖到的 r,肯定也能被 l+1 覆盖到。因此,r 只需要一路向右,永不回头。这样复杂度就降到了 $O(N)$。 改动一行代码即可,把 r = l + 1 挪到 while l 的循环外即可。 |
|