中等
給你一個整數數組 nums
和一個整數 k
,請你返回子數組內所有元素的乘積嚴格小于 k
的連續子數組的數目。
示例 1:
輸入:nums = [10,5,2,6], k = 100
輸出:8
解釋:8 個乘積小于 100 的子數組分別為:[10]、[5]、[2]、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。
需要注意的是 [10,5,2] 并不是乘積小于 100 的子數組。
示例 2:
輸入:nums = [1,2,3], k = 0
輸出:0
提示:
1 <= nums.length <= 3 * 104
1 <= nums[i] <= 1000
0 <= k <= 106
1. 題解
class Solution {
public int numSubarrayProductLessThanK(int[] nums, int k) {
if (k <= 1) {
return 0;
}
int ans = 0; //記錄符合條件的子數組數目
int prod = 1; // 窗口內元素的乘積, 初始化為1
int left = 0; //窗口左邊界
for (int right = 0; right < nums.length; right++) {
prod *= nums[right]; // 將當前元素加入窗口, 更新乘積
while (prod >= k) { // 乘積>=k, 需要縮小窗口
prod /= nums[left];
left++; // 縮小窗口
}
// 對于固定的 right,有 right-left+1 個合法的左端點
ans += right - left + 1;
}
return ans;
}
}
核心原理:滑動窗口
滑動窗口適用于解決 “連續子數組” 相關問題。在本題中,具體邏輯如下:
- 右指針擴張:不斷向右移動右指針
right
,將元素加入窗口,使窗口內元素乘積prod
增大。 - 左指針收縮:當窗口內元素乘積
prod
≥k
時,通過右移左指針left
縮小窗口,直到乘積小于k
。 - 統計子數組數目:對于每個右指針
right
,當窗口合法時,計算以right
結尾的所有合法子數組數目。
作者:靈茶山艾府
鏈接:713. 乘積小于 K 的子數組 - 力扣(LeetCode)
來源:力扣(LeetCode)