Skip to content

Commit

Permalink
Update 0862. 和至少为 K 的最短子数组.md
Browse files Browse the repository at this point in the history
  • Loading branch information
itcharge committed Jan 8, 2024
1 parent 9ad7c09 commit 8a8154b
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions Solutions/0862. 和至少为 K 的最短子数组.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,14 @@
对于区间 $[j, i)$ 来说,我们应该尽可能的减少不成立的区间枚举。

1. 对于某个区间 $[j, i)$ 来说,如果 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$,那么大于 $i$ 的索引值就不用再进行枚举了,不可能比 $i - j$ 的差值更优了。此时我们应该尽可能的向右移动 $j$,从而使得 $i - j$ 更小。
2. 对于某个区间 $[j, i)$ 来说,如果 $pre\underline{}sum[j] \ge pre\underline{}sum[i]$,对于任何大于等于 $i$ 的索引值 $r$ 来说,$pre\underline{}sum[r] - pre\underline{}sum[i]$ 一定比 $pre\underline{}sum[i] - pre\underline{}sum[j]$ 更小且长度更小此时 $pre\underline{}sum[j]$ 可以直接忽略掉。
2. 对于某个区间 $[j, i)$ 来说,如果 $pre\underline{}sum[j] \ge pre\underline{}sum[i]$,对于任何大于等于 $i$ 的索引值 $r$ 来说,$pre\underline{}sum[r] - pre\underline{}sum[i]$ 一定比 $pre\underline{}sum[i] - pre\underline{}sum[j]$ 更小且长度更小此时 $pre\underline{}sum[j]$ 可以直接忽略掉。

因此,我们可以使用单调队列来保存单调递增的 $pre\underline{}sum[x]$ 值的下标
因此,我们可以使用单调队列来维护单调递增的前缀数组 $pre\underline{}sum$。其中存放了下标 $x:x_0, x_1, …$,满足 $pre\underline{}sum[x_0] < pre\underline{}sum[x_1] < …$ 单调递增

对于每一个位置 $i$ 我们可以判断其之前存入在单调队列中的 $pre\underline{}sum[j]$ 值,如果 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$,则更新答案,并将 $j$ 从队头位置弹出。直到 $pre\underline{}sum[i] - pre\underline{}sum[j] < k$ 时为止。

如果队尾 $pre\underline{}sum[j] \ge pre\underline{}sum[i]$,那么 $$

使用一重循环遍历 $i$,对于 $pre\underline{}sum[i]$,我们希望使用某个数据结构,能够使得在满足 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$ 当前前提下,能够尽可能的向右移动 $j$,从而使得 $i - j$ 最小。
1. 使用一重循环遍历位置 $i$,将当前位置 $i$ 存入倒掉队列中。
2. 对于每一个位置 $i$,如果单调队列不为空,则可以判断其之前存入在单调队列中的 $pre\underline{}sum[j]$ 值,如果 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$,则更新答案,并将 $j$ 从队头位置弹出。直到不再满足 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$ 时为止(即 $pre\underline{}sum[i] - pre\underline{}sum[j] < k$)。
3. 如果队尾 $pre\underline{}sum[j] \ge pre\underline{}sum[i]$,那么说明以后无论如何都不会再考虑 $pre\underline{}sum[j]$ 了,则将其从队尾弹出。
4. 最后遍历完返回答案。

### 思路 1:代码

Expand All @@ -74,18 +73,18 @@ class Solution:
def shortestSubarray(self, nums: List[int], k: int) -> int:
size = len(nums)

# 优化 1
pre_sum = [0 for _ in range(size + 1)]
for i in range(size):
pre_sum[i + 1] = pre_sum[i] + nums[i]

ans = float('inf')
queue = collections.deque()

for i in range(size + 1):
# 优化 1
for i in range(size + 1):
# 优化 2
while queue and pre_sum[i] - pre_sum[queue[0]] >= k:
ans = min(ans, i - queue.popleft())
# 优化 2
while queue and pre_sum[queue[-1]] >= pre_sum[i]:
queue.pop()
queue.append(i)
Expand Down

0 comments on commit 8a8154b

Please sign in to comment.