Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bd0eb2c

Browse files
committed
feat: update solutions to lc problem: No.3362
1 parent 51a192d commit bd0eb2c

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

‎solution/3300-3399/3362.Zero Array Transformation III/README.md‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,34 @@ tags:
9797

9898
<!-- solution:start -->
9999

100-
### 方法一:贪心 + 差分数组 + 优先队列(大根堆)
100+
### 方法一:贪心 + 差分数组 + 优先队列
101+
102+
我们希望尽可能多地「移除」区间查询,但又要保证对每个位置 $i$ 来说,被选中、覆盖到它的查询次数 $s(i)$ 至少达到原数组值 $\textit{nums}[i],ドル这样才能把该位置的值"减"到 0 或以下。如果对于某个位置 $i$ 无法满足 $s(i)\ge\textit{nums}[i],ドル就说明再多选任何查询都不可能让该位置归零,返回 $-1$。
103+
104+
为了做到这一点,我们按查询区间的左端点从小到大遍历,并维护:
105+
106+
1. **差分数组** `d`:用于记录当前已应用的查询在何处分界——当我们在区间 $[l,r]$ 上"应用"一次查询时,立刻在差分数组位置 `d[l] += 1`,并在 `d[r+1] -= 1`,这样在遍历到下标 $i$ 时累加前缀和就能知道有多少次查询覆盖了 $i$。
107+
2. **最大堆** `pq`:存放当前「候选」区间查询的右端点(取负数以便 Python 最小堆模拟最大堆)。为什么选「最晚结束」的区间?因为它能覆盖更远的位置,我们的贪心策略是:**在每个 $i$ 处,只在必要时才摘取堆顶最长的区间来增加一次覆盖**,这样能为后续位置保留更多可用的区间。
108+
109+
具体步骤如下:
110+
111+
1. 先对 `queries` 按左端点 `l` 升序排序;
112+
2. 初始化差分数组 `d` 长度为 `n+1`(用来处理 `r+1` 处的减操作),以及当前覆盖次数 `s=0`、堆指针 `j=0`;
113+
3. 从 $i=0$ 遍历到 $n-1$:
114+
115+
- 先把 `d[i]` 累加到 `s`,即时更新已有的覆盖次数;
116+
- 将所有左端点 $\le i$ 的查询 $[l,r]$ 压入最大堆 `pq`(存 `-r`),并推进 `j`;
117+
- 当当前覆盖次数 `s` 小于所需值 `nums[i]`,且堆不空且堆顶区间仍能覆盖 $i$(即 $-pq[0]\ge i$)时:
118+
119+
1. 弹出堆顶(最长的区间),等价于"应用"这次查询;
120+
2.`s += 1` 并在 `d[r+1] -= 1`(使得在跨过 `r` 后覆盖次数自动回退);
121+
122+
- 重复上述步骤,直到 `s>=nums[i]` 或无法再选区间;
123+
- 若此时 `s<nums[i]`,说明无法将位置 $i$ 归零,直接返回 $-1$。
124+
125+
4. 全部遍历完毕后,剩在堆里的区间都是「未被弹出」的,也就是真正被**保留**(即未被用来完成"归零"任务)的查询。堆大小即为答案。
126+
127+
时间复杂度 $O(n + m \times \log m),ドル空间复杂度 $O(n + m),ドル其中 $n$ 是数组的长度,而 $m$ 是查询的个数。
101128

102129
<!-- tabs:start -->
103130

‎solution/3300-3399/3362.Zero Array Transformation III/README_EN.md‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,34 @@ tags:
9494

9595
<!-- solution:start -->
9696

97-
### Solution 1
97+
### Solution 1: Greedy + Difference Array + Priority Queue
98+
99+
We want to "remove" as many interval queries as possible, while ensuring that for each position $i,ドル the number of selected queries covering it, $s(i),ドル is at least the original array value $\textit{nums}[i],ドル so that the value at that position can be reduced to 0 or below. If for some position $i$ we cannot satisfy $s(i) \ge \textit{nums}[i],ドル it means that no matter how many more queries we select, it is impossible to make that position zero, so we return $-1$.
100+
101+
To achieve this, we traverse the queries in order of their left endpoints and maintain:
102+
103+
1. **Difference array** `d`: Used to record where the currently applied queries take effect—when we "apply" a query on the interval $[l, r],ドル we immediately do `d[l] += 1` and `d[r+1] -= 1`. This way, when traversing to index $i,ドル the prefix sum tells us how many queries cover $i$.
104+
2. **Max heap** `pq`: Stores the right endpoints of the current "candidate" interval queries (store as negative numbers to simulate a max heap in Python's min heap). Why choose the "latest ending" interval? Because it can cover farther positions. Our greedy strategy is: **at each $i,ドル only pick the longest interval from the heap when necessary to increase coverage**, so that more intervals are available for subsequent positions.
105+
106+
The specific steps are as follows:
107+
108+
1. Sort `queries` by the left endpoint `l` in ascending order;
109+
2. Initialize the difference array `d` with length `n+1` (to handle the decrement at `r+1`), and set the current coverage count `s=0`, heap pointer `j=0`;
110+
3. For $i=0$ to $n-1$:
111+
112+
- First, add `d[i]` to `s` to update the current coverage count;
113+
- Push all queries $[l, r]$ with left endpoint $\le i$ into the max heap `pq` (store `-r`), and advance `j`;
114+
- While the current coverage `s` is less than the required value `nums[i]`, and the heap is not empty, and the top interval in the heap still covers $i$ (i.e., $-pq[0] \ge i$):
115+
116+
1. Pop the top of the heap (the longest interval), which is equivalent to "applying" this query;
117+
2. Increment `s` by 1 and do `d[r+1] -= 1` (so that after passing $r,ドル the coverage count automatically decreases);
118+
119+
- Repeat the above steps until `s \ge nums[i]` or no more intervals can be selected;
120+
- If at this point `s < nums[i]`, it means it is impossible to make position $i$ zero, so return $-1$.
121+
122+
4. After traversing all positions, the intervals remaining in the heap are those that were **not popped**, i.e., the queries that are truly **retained** (not used for the "zeroing" task). The heap size is the answer.
123+
124+
The time complexity is $O(n + m \times \log m),ドル and the space complexity is $O(n + m),ドル where $n$ is the length of the array and $m$ is the number of queries.
98125

99126
<!-- tabs:start -->
100127

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /