57
57
对于区间 $[ j, i)$ 来说,我们应该尽可能的减少不成立的区间枚举。
58
58
59
59
1 . 对于某个区间 $[ j, i)$ 来说,如果 $pre\underline{}sum[ i] - pre\underline{}sum[ j] \ge k,ドル那么大于 $i$ 的索引值就不用再进行枚举了,不可能比 $i - j$ 的差值更优了。此时我们应该尽可能的向右移动 $j,ドル从而使得 $i - j$ 更小。
60
- 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] $ 可以直接忽略掉。
60
+ 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] $ 可以直接忽略掉。
61
61
62
- 因此,我们可以使用单调队列来保存单调递增的 $pre\underline{}sum[ x ] $ 值的下标 。
62
+ 因此,我们可以使用单调队列来维护单调递增的前缀数组 $pre\underline{}sum$。其中存放了下标 $x : x_0 , x_1, ...,ドル满足 $pre\underline{}sum [ x_0 ] < pre\underline{}sum [ x_1 ] < ...$ 单调递增 。
63
63
64
- 对于每一个位置 $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$ 时为止。
65
-
66
- 如果队尾 $pre\underline{}sum[ j] \ge pre\underline{}sum[ i] ,ドル那么 $$
67
-
68
- 使用一重循环遍历 $i,ドル对于 $pre\underline{}sum[ i] ,ドル我们希望使用某个数据结构,能够使得在满足 $pre\underline{}sum[ i] - pre\underline{}sum[ j] \ge k$ 当前前提下,能够尽可能的向右移动 $j,ドル从而使得 $i - j$ 最小。
64
+ 1 . 使用一重循环遍历位置 $i,ドル将当前位置 $i$ 存入倒掉队列中。
65
+ 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$)。
66
+ 3 . 如果队尾 $pre\underline{}sum[ j] \ge pre\underline{}sum[ i] ,ドル那么说明以后无论如何都不会再考虑 $pre\underline{}sum[ j] $ 了,则将其从队尾弹出。
67
+ 4 . 最后遍历完返回答案。
69
68
70
69
### 思路 1:代码
71
70
@@ -74,18 +73,18 @@ class Solution:
74
73
def shortestSubarray (self , nums : List[int ], k : int ) -> int :
75
74
size = len (nums)
76
75
76
+ # 优化 1
77
77
pre_sum = [0 for _ in range (size + 1 )]
78
78
for i in range (size):
79
79
pre_sum[i + 1 ] = pre_sum[i] + nums[i]
80
80
81
81
ans = float (' inf' )
82
82
queue = collections.deque()
83
83
84
- for i in range (size + 1 ):
85
- # 优化 1
84
+ for i in range (size + 1 ):
85
+ # 优化 2
86
86
while queue and pre_sum[i] - pre_sum[queue[0 ]] >= k:
87
87
ans = min (ans, i - queue.popleft())
88
- # 优化 2
89
88
while queue and pre_sum[queue[- 1 ]] >= pre_sum[i]:
90
89
queue.pop()
91
90
queue.append(i)
0 commit comments