From 8a8154b4683feb3a487d30a160e833a2ba798f16 Mon Sep 17 00:00:00 2001 From: ITCharge Date: Mon, 8 Jan 2024 20:08:50 +0800 Subject: [PATCH] =?UTF-8?q?Update=200862.=20=E5=92=8C=E8=87=B3=E5=B0=91?= =?UTF-8?q?=E4=B8=BA=20K=20=E7=9A=84=E6=9C=80=E7=9F=AD=E5=AD=90=E6=95=B0?= =?UTF-8?q?=E7=BB=84.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...55\345\255\220\346\225\260\347\273\204.md" | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git "a/Solutions/0862. \345\222\214\350\207\263\345\260\221\344\270\272 K \347\232\204\346\234\200\347\237\255\345\255\220\346\225\260\347\273\204.md" "b/Solutions/0862. \345\222\214\350\207\263\345\260\221\344\270\272 K \347\232\204\346\234\200\347\237\255\345\255\220\346\225\260\347\273\204.md" index 4b154852..49d4e76b 100644 --- "a/Solutions/0862. \345\222\214\350\207\263\345\260\221\344\270\272 K \347\232\204\346\234\200\347\237\255\345\255\220\346\225\260\347\273\204.md" +++ "b/Solutions/0862. \345\222\214\350\207\263\345\260\221\344\270\272 K \347\232\204\346\234\200\347\237\255\345\255\220\346\225\260\347\273\204.md" @@ -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:代码 @@ -74,6 +73,7 @@ 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] @@ -81,11 +81,10 @@ class Solution: 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)