@@ -58,22 +58,11 @@ tags:
58
58
59
59
我们可以用双指针维护一个滑动窗口,窗口内所有元素的乘积小于 $k$。
60
60
61
- 初始时,左右指针都指向下标 0,然后不断地右移右指针,将元素加入窗口,此时判断窗口内所有元素的乘积是否大于等于 $k$,如果大于等于 $k$,则不断地左移左指针,将元素移出窗口,直到窗口内所有元素的乘积小于 $k$。然后我们记录此时的窗口大小,即为以右指针为右端点的满足条件的子数组个数,将其加入答案 。
61
+ 定义两个指针 $l$ 和 $r$ 分别指向滑动窗口的左右边界,初始时 $l = r = 0$。我们用一个变量 $p$ 记录窗口内所有元素的乘积,初始时 $p = 1$ 。
62
62
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$ 到达数组的末尾 。
64
64
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)$。
77
66
78
67
<!-- tabs:start -->
79
68
@@ -82,13 +71,14 @@ for (int i = 0, j = 0; i < n; ++i) {
82
71
``` python
83
72
class Solution :
84
73
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
92
82
return ans
93
83
```
94
84
@@ -97,13 +87,14 @@ class Solution:
97
87
``` java
98
88
class Solution {
99
89
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++ ];
105
96
}
106
- ans += i - j + 1 ;
97
+ ans += r - l + 1 ;
107
98
}
108
99
return ans;
109
100
}
@@ -116,11 +107,14 @@ class Solution {
116
107
class Solution {
117
108
public:
118
109
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;
124
118
}
125
119
return ans;
126
120
}
@@ -130,30 +124,32 @@ public:
130
124
#### Go
131
125
132
126
```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
143
138
}
144
139
```
145
140
146
141
#### TypeScript
147
142
148
143
``` ts
149
144
function 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 ++ ];
155
151
}
156
- ans += i - j + 1 ;
152
+ ans += r - l + 1 ;
157
153
}
158
154
return ans ;
159
155
}
@@ -164,22 +160,20 @@ function numSubarrayProductLessThanK(nums: number[], k: number): number {
164
160
``` rust
165
161
impl Solution {
166
162
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 ;
169
174
}
170
175
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
183
177
}
184
178
}
185
179
```
@@ -194,14 +188,13 @@ impl Solution {
194
188
*/
195
189
var numSubarrayProductLessThanK = function (nums , k ) {
196
190
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++ ];
203
196
}
204
- ans += i - j + 1 ;
197
+ ans += r - l + 1 ;
205
198
}
206
199
return ans;
207
200
};
@@ -212,17 +205,39 @@ var numSubarrayProductLessThanK = function (nums, k) {
212
205
``` kotlin
213
206
class Solution {
214
207
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 ++ ];
222
237
}
223
- count + = right - left + 1
238
+ ans += r - l + 1 ;
224
239
}
225
- return count
240
+ return ans ;
226
241
}
227
242
}
228
243
```
0 commit comments