@@ -58,22 +58,11 @@ tags:
5858
5959我们可以用双指针维护一个滑动窗口,窗口内所有元素的乘积小于 $k$。
6060
61- 初始时,左右指针都指向下标 0,然后不断地右移右指针,将元素加入窗口,此时判断窗口内所有元素的乘积是否大于等于 $k$,如果大于等于 $k$,则不断地左移左指针,将元素移出窗口,直到窗口内所有元素的乘积小于 $k$。然后我们记录此时的窗口大小,即为以右指针为右端点的满足条件的子数组个数,将其加入答案 。
61+ 定义两个指针 $l$ 和 $r$ 分别指向滑动窗口的左右边界,初始时 $l = r = 0$。我们用一个变量 $p$ 记录窗口内所有元素的乘积,初始时 $p = 1$ 。
6262
63- 当右指针移动到数组末尾时,即可得到答案 。
63+ 每次,我们将 $r$ 右移一位,将 $r$ 指向的元素 $x$ 加入窗口,更新 $p = p \times x$。然后,如果 $p \geq k$,我们循环地将 $l$ 右移一位,并更新 $p = p \div \text{nums} [ l ] $,直到 $p < k$ 或者 $l \gt r$ 为止。这样,以 $r$ 结尾的、乘积小于 $k$ 的连续子数组的个数即为 $r - l + 1$。然后我们将答案加上这个数量,并继续移动 $r$,直到 $r$ 到达数组的末尾 。
6464
65- 时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组的长度。
66-
67- 以下是双指针的常用算法模板:
68-
69- ``` java
70- for (int i = 0 , j = 0 ; i < n; ++ i) {
71- while (j < i && check(j, i)) {
72- ++ j;
73- }
74- // 具体问题的逻辑
75- }
76- ```
65+ 时间复杂度 $O(n)$,其中 $n$ 为数组的长度。空间复杂度 $O(1)$。
7766
7867<!-- tabs:start -->
7968
@@ -82,13 +71,14 @@ for (int i = 0, j = 0; i < n; ++i) {
8271``` python
8372class Solution :
8473 def numSubarrayProductLessThanK (self , nums : List[int ], k : int ) -> int :
85- ans, s, j = 0 , 1 , 0
86- for i, v in enumerate (nums):
87- s *= v
88- while j <= i and s >= k:
89- s //= nums[j]
90- j += 1
91- ans += i - j + 1
74+ ans = l = 0
75+ p = 1
76+ for r, x in enumerate (nums):
77+ p *= x
78+ while l <= r and p >= k:
79+ p //= nums[l]
80+ l += 1
81+ ans += r - l + 1
9282 return ans
9383```
9484
@@ -97,13 +87,14 @@ class Solution:
9787``` java
9888class Solution {
9989 public int numSubarrayProductLessThanK (int [] nums , int k ) {
100- int ans = 0 ;
101- for (int i = 0 , j = 0 , s = 1 ; i < nums. length; ++ i) {
102- s *= nums[i];
103- while (j <= i && s >= k) {
104- s /= nums[j++ ];
90+ int ans = 0 , l = 0 ;
91+ int p = 1 ;
92+ for (int r = 0 ; r < nums. length; ++ r) {
93+ p *= nums[r];
94+ while (l <= r && p >= k) {
95+ p /= nums[l++ ];
10596 }
106- ans += i - j + 1 ;
97+ ans += r - l + 1 ;
10798 }
10899 return ans;
109100 }
@@ -116,11 +107,14 @@ class Solution {
116107class Solution {
117108public:
118109 int numSubarrayProductLessThanK(vector<int >& nums, int k) {
119- int ans = 0;
120- for (int i = 0, j = 0, s = 1; i < nums.size(); ++i) {
121- s * = nums[ i] ;
122- while (j <= i && s >= k) s /= nums[ j++] ;
123- ans += i - j + 1;
110+ int ans = 0, l = 0;
111+ int p = 1;
112+ for (int r = 0; r < nums.size(); ++r) {
113+ p * = nums[ r] ;
114+ while (l <= r && p >= k) {
115+ p /= nums[ l++] ;
116+ }
117+ ans += r - l + 1;
124118 }
125119 return ans;
126120 }
@@ -130,30 +124,32 @@ public:
130124#### Go
131125
132126```go
133- func numSubarrayProductLessThanK(nums []int, k int) int {
134- ans := 0
135- for i, j, s := 0, 0, 1; i < len(nums); i++ {
136- s *= nums[i]
137- for ; j <= i && s >= k; j++ {
138- s /= nums[j]
139- }
140- ans += i - j + 1
141- }
142- return ans
127+ func numSubarrayProductLessThanK(nums []int, k int) (ans int) {
128+ l, p := 0, 1
129+ for r, x := range nums {
130+ p *= x
131+ for l <= r && p >= k {
132+ p /= nums[l]
133+ l++
134+ }
135+ ans += r - l + 1
136+ }
137+ return
143138}
144139```
145140
146141#### TypeScript
147142
148143``` ts
149144function numSubarrayProductLessThanK(nums : number [], k : number ): number {
150- let ans = 0 ;
151- for (let i = 0 , j = 0 , s = 1 ; i < nums .length ; ++ i ) {
152- s *= nums [i ];
153- while (j <= i && s >= k ) {
154- s /= nums [j ++ ];
145+ const n = nums .length ;
146+ let [ans, l, p] = [0 , 0 , 1 ];
147+ for (let r = 0 ; r < n ; ++ r ) {
148+ p *= nums [r ];
149+ while (l <= r && p >= k ) {
150+ p /= nums [l ++ ];
155151 }
156- ans += i - j + 1 ;
152+ ans += r - l + 1 ;
157153 }
158154 return ans ;
159155}
@@ -164,22 +160,20 @@ function numSubarrayProductLessThanK(nums: number[], k: number): number {
164160``` rust
165161impl Solution {
166162 pub fn num_subarray_product_less_than_k (nums : Vec <i32 >, k : i32 ) -> i32 {
167- if k <= 1 {
168- return 0 ;
163+ let mut ans = 0 ;
164+ let mut l = 0 ;
165+ let mut p = 1 ;
166+
167+ for (r , & x ) in nums . iter (). enumerate () {
168+ p *= x ;
169+ while l <= r && p >= k {
170+ p /= nums [l ];
171+ l += 1 ;
172+ }
173+ ans += (r - l + 1 ) as i32 ;
169174 }
170175
171- let mut res = 0 ;
172- let mut product = 1 ;
173- let mut i = 0 ;
174- nums . iter (). enumerate (). for_each (| (j , v )| {
175- product *= v ;
176- while product >= k {
177- product /= nums [i ];
178- i += 1 ;
179- }
180- res += j - i + 1 ;
181- });
182- res as i32
176+ ans
183177 }
184178}
185179```
@@ -194,14 +188,13 @@ impl Solution {
194188 */
195189var numSubarrayProductLessThanK = function (nums , k ) {
196190 const n = nums .length ;
197- let ans = 0 ;
198- let s = 1 ;
199- for (let i = 0 , j = 0 ; i < n; ++ i) {
200- s *= nums[i];
201- while (j <= i && s >= k) {
202- s = Math .floor (s / nums[j++ ]);
191+ let [ans, l, p] = [0 , 0 , 1 ];
192+ for (let r = 0 ; r < n; ++ r) {
193+ p *= nums[r];
194+ while (l <= r && p >= k) {
195+ p /= nums[l++ ];
203196 }
204- ans += i - j + 1 ;
197+ ans += r - l + 1 ;
205198 }
206199 return ans;
207200};
@@ -212,17 +205,39 @@ var numSubarrayProductLessThanK = function (nums, k) {
212205``` kotlin
213206class Solution {
214207 fun numSubarrayProductLessThanK (nums : IntArray , k : Int ): Int {
215- var left = 0
216- var count = 0
217- var product = 1
218- nums.forEachIndexed { right, num ->
219- product * = num
220- while (product >= k && left <= right) {
221- product / = nums[left++ ]
208+ var ans = 0
209+ var l = 0
210+ var p = 1
211+
212+ for (r in nums.indices) {
213+ p * = nums[r]
214+ while (l <= r && p >= k) {
215+ p / = nums[l]
216+ l++
217+ }
218+ ans + = r - l + 1
219+ }
220+
221+ return ans
222+ }
223+ }
224+ ```
225+
226+ #### C#
227+
228+ ``` cs
229+ public class Solution {
230+ public int NumSubarrayProductLessThanK (int [] nums , int k ) {
231+ int ans = 0 , l = 0 ;
232+ int p = 1 ;
233+ for (int r = 0 ; r < nums .Length ; ++ r ) {
234+ p *= nums [r ];
235+ while (l <= r && p >= k ) {
236+ p /= nums [l ++ ];
222237 }
223- count + = right - left + 1
238+ ans += r - l + 1 ;
224239 }
225- return count
240+ return ans ;
226241 }
227242}
228243```
0 commit comments