题目描述
思路解析动画文字版
记住「右扩乘、超了就左缩除、每步加 right−left+1」,下面每一格都在套它。
这一行是数组,全是正整数。窗口从空开始、乘积 prod=1,右指针从左往右一格格扩,我们盯着 prod 和 ans 怎么变。
右指针到第 0 位(值 10),乘进窗口,乘积变成 10。仍然 < k=100,窗口合法。
窗口 [0, 0] 合法。以第 0 位结尾、左端从 0 到 0 的子数组乘积都 < 100,共 1 个,答案加 1,累计 1。
右指针到第 1 位(值 5),乘进窗口,乘积变成 50。仍然 < k=100,窗口合法。
窗口 [0, 1] 合法。以第 1 位结尾、左端从 0 到 1 的子数组乘积都 < 100,共 2 个,答案加 2,累计 3。
右指针到第 2 位(值 2),乘进窗口,乘积变成 100。它 ≥ k=100(红),窗口里乘积太大,下一步要左缩。
把左指针右移 1 步、依次除掉移出位,乘积回到 10(<100)。现在窗口是 [1, 2],以第 2 位结尾的合法子数组有 2 个(左端可取 1 到 2),答案加 2,累计 5。
右指针到第 3 位(值 6),乘进窗口,乘积变成 60。仍然 < k=100,窗口合法。
窗口 [1, 3] 合法。以第 3 位结尾、左端从 1 到 3 的子数组乘积都 < 100,共 3 个,答案加 3,累计 8。
右指针到第 4 位(值 1),乘进窗口,乘积变成 60。仍然 < k=100,窗口合法。
窗口 [1, 4] 合法。以第 4 位结尾、左端从 1 到 4 的子数组乘积都 < 100,共 4 个,答案加 4,累计 12。
右指针到第 5 位(值 8),乘进窗口,乘积变成 480。它 ≥ k=100(红),窗口里乘积太大,下一步要左缩。
把左指针右移 1 步、依次除掉移出位,乘积回到 96(<100)。现在窗口是 [2, 5],以第 5 位结尾的合法子数组有 4 个(左端可取 2 到 5),答案加 4,累计 16。
右指针到第 6 位(值 3),乘进窗口,乘积变成 288。它 ≥ k=100(红),窗口里乘积太大,下一步要左缩。
把左指针右移 2 步、依次除掉移出位,乘积回到 24(<100)。现在窗口是 [4, 6],以第 6 位结尾的合法子数组有 3 个(左端可取 4 到 6),答案加 3,累计 19。
右指针到第 7 位(值 2),乘进窗口,乘积变成 48。仍然 < k=100,窗口合法。
窗口 [4, 7] 合法。以第 7 位结尾、左端从 4 到 7 的子数组乘积都 < 100,共 4 个,答案加 4,累计 23。
右指针到第 8 位(值 4),乘进窗口,乘积变成 192。它 ≥ k=100(红),窗口里乘积太大,下一步要左缩。
把左指针右移 2 步、依次除掉移出位,乘积回到 24(<100)。现在窗口是 [6, 8],以第 8 位结尾的合法子数组有 3 个(左端可取 6 到 8),答案加 3,累计 26。
右指针到第 9 位(值 7),乘进窗口,乘积变成 168。它 ≥ k=100(红),窗口里乘积太大,下一步要左缩。
把左指针右移 1 步、依次除掉移出位,乘积回到 56(<100)。现在窗口是 [7, 9],以第 9 位结尾的合法子数组有 3 个(左端可取 7 到 9),答案加 3,累计 29。
扫完全程,把每个右端点贡献的「right−left+1」加起来,一共 29 个乘积小于 100 的子数组。右、左指针各只走一遍,O(n)。
边界先想清:k≤1 返回 0、全合法时是所有子数组数、单元素看它本身。
面试常考:用「以 right 结尾」论证不重不漏,以及正整数这个前提为何关键。
参考代码
from typing import Listclass Solution: def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int: if k <= 1: return 0 prod = 1 left = ans = 0 for right, x in enumerate(nums): prod *= x while prod >= k: prod //= nums[left] left += 1 ans += right - left + 1 return ans复杂度
- 时间:O(n),左右指针各只前进一遍,每个元素进出窗口各一次
- 空间:O(1),只用 left/prod/ans 几个变量
易错点
面试追问把动画讲成自己的话
追问为什么按「以每个 right 结尾」来数,就不重不漏?
追问如果数组里可能有 0 或负数怎么办?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
水果成篮
LeetCode 904 · 中等 · 沿着 滑动窗口套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题