题目描述
思路解析动画文字版
记住「删的段和 ≡ need;找余数 = target 的最近前缀」,下面每帧都在套它。
先算整段和 29,29 mod 6 = 5 就是 need。目标:删一段使其和 ≡ 5 (mod 6),剩下的就能被 6 整除。先把空前缀记下:余数 0 在下标 −1。
读第 0 位 4,累进前缀和再取模:prefix 从 0 变成 4。下一步算 target、去哈希表里找余数 = target 的最近位置。
target = 5 不在表里,没有以这里结尾的可删段。把当前前缀余数记下 last[4] = 0(只留最近的,求最短才对),留给后面用。
读第 1 位 3,累进前缀和再取模:prefix 从 4 变成 1。下一步算 target、去哈希表里找余数 = target 的最近位置。
target = 2 不在表里,没有以这里结尾的可删段。把当前前缀余数记下 last[1] = 1(只留最近的,求最短才对),留给后面用。
读第 2 位 1,累进前缀和再取模:prefix 从 1 变成 2。下一步算 target、去哈希表里找余数 = target 的最近位置。
target = 3 不在表里,没有以这里结尾的可删段。把当前前缀余数记下 last[2] = 2(只留最近的,求最短才对),留给后面用。
读第 3 位 4,累进前缀和再取模:prefix 从 2 变成 0。下一步算 target、去哈希表里找余数 = target 的最近位置。
target = 1 在表里(最近下标 1)!删掉下标 2…3 这段(窗口),剩余和就 ≡ 0 (mod 6),这段长 2。比之前更短,最短刷新成 2。 再把 last[0] 更新成 3。
读第 4 位 2,累进前缀和再取模:prefix 从 0 变成 2。下一步算 target、去哈希表里找余数 = target 的最近位置。
target = 3 不在表里,没有以这里结尾的可删段。把当前前缀余数记下 last[2] = 4(只留最近的,求最短才对),留给后面用。
读第 5 位 5,累进前缀和再取模:prefix 从 2 变成 1。下一步算 target、去哈希表里找余数 = target 的最近位置。
target = 2 在表里(最近下标 4)!删掉下标 5…5 这段(窗口),剩余和就 ≡ 0 (mod 6),这段长 1。比之前更短,最短刷新成 1。 再把 last[1] 更新成 5。
读第 6 位 7,累进前缀和再取模:prefix 从 1 变成 2。下一步算 target、去哈希表里找余数 = target 的最近位置。
target = 3 不在表里,没有以这里结尾的可删段。把当前前缀余数记下 last[2] = 6(只留最近的,求最短才对),留给后面用。
读第 7 位 3,累进前缀和再取模:prefix 从 2 变成 5。下一步算 target、去哈希表里找余数 = target 的最近位置。
target = 0 在表里(最近下标 3)!删掉下标 4…7 这段(窗口),剩余和就 ≡ 0 (mod 6),这段长 4。没比当前最短 1 更短,保持。 再把 last[5] 更新成 7。
扫完全程,最短只需删窗口里这 1 个(下标 5…5,值 5)。删掉后剩余和 24,正好 4 × 6,能被 6 整除,答案 1。靠「余数 = target 的最近前缀」一遍扫描就找到了。
边界先想清:本就整除→0、只能删全部→−1、单元素可解。
认出「前缀和取模 + 哈希」母题,和 LC523/525 一脉相承,区别只在存哪个下标、要不要再查距离。
参考代码
from typing import Listclass Solution: def minSubarray(self, nums: List[int], p: int) -> int: need = sum(nums) % p if need == 0: return 0 last = {0: -1} prefix = 0 ans = len(nums) for i, x in enumerate(nums): prefix = (prefix + x) % p target = (prefix - need) % p if target in last: ans = min(ans, i - last[target]) last[prefix] = i return -1 if ans == len(nums) else ans复杂度
- 时间:O(n),一遍扫描,哈希查/插 O(1)
- 空间:O(min(n, p)),哈希表最多存 p 个不同余数
易错点
面试追问把动画讲成自己的话
追问这题和 LC523/525「前缀和取模 / 等量」有什么共性和区别?
追问为什么余数最多只有 p 种,空间能压到 O(min(n,p))?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。再去主线里挑下一道练手。
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题