[LeetCode] 713. Subarray Product Less Than K 子數組乘積小於K


 

Your are given an array of positive integers nums.

Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k.

Example 1:

Input: nums = [10, 5, 2, 6], k = 100
Output: 8
Explanation: The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6].
Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.

Note:

  • 0 < nums.length <= 50000.
  • 0 < nums[i] < 1000.
  • 0 <= k < 10^6.

 

這道題給了我們一個數組和一個數字K,讓求子數組且滿足乘積小於K的個數。既然是子數組,那么必須是連續的,所以肯定不能給數組排序了,這道題好在限定了輸入數字都是正數,能稍稍好做一點。博主剛開始用的是暴力搜索的方法來做的,就是遍歷所有的子數組算乘積和K比較,兩個 for 循環就行了,但是 OJ 不答應。於是上網搜大神們的解法,思路很贊。相當於是一種滑動窗口的解法,維護一個數字乘積剛好小於k的滑動窗口,用變量 left 來記錄其左邊界的位置,右邊界i就是當前遍歷到的位置。遍歷原數組,用 prod 乘上當前遍歷到的數字,然后進行 while 循環,如果 prod 大於等於k,則滑動窗口的左邊界需要向右移動一位,刪除最左邊的數字,那么少了一個數字,乘積就會改變,所以用 prod 除以最左邊的數字,然后左邊右移一位,即 left 自增1。當確定了窗口的大小后,就可以統計子數組的個數了,就是窗口的大小。為啥呢,比如 [5 2 6] 這個窗口,k還是 100,右邊界剛滑到6這個位置,這個窗口的大小就是包含6的子數組乘積小於k的個數,即 [6], [2 6], [5 2 6],正好是3個。所以窗口每次向右增加一個數字,然后左邊去掉需要去掉的數字后,窗口的大小就是新的子數組的個數,每次加到結果 res 中即可,參見代碼如下:

 

class Solution {
public:
    int numSubarrayProductLessThanK(vector<int>& nums, int k) {
        if (k <= 1) return 0;
        int res = 0, prod = 1, left = 0;
        for (int i = 0; i < nums.size(); ++i) {
            prod *= nums[i];
            while (left <= i && prod >= k) prod /= nums[left++];
            res += i - left + 1;
        }
        return res;
    }
};

 

討論:這道題其實可有很多種變形,比如當數組的數字有負數和0該怎么做?或者求的不是子數組,而是子序列該怎么做,子序列的話就可以排序啦,當然還是需要都是正數,才有排序的意義,博主覺得如果有負數和0,是不是只能暴力破解了,或者使用 Maximum Product Subarray 中的方法?再有一種的變形就是求子數組或子序列乘積剛好等於k,這就跟 Subarray Sum Equals K 和 Maximum Size Subarray Sum Equals k 這兩題中使用的方法類似吧,建立子數組和其乘積之間的映射來快速找到。

歡迎大家在評論區留言討論!

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/713

 

類似題目:

Maximum Product Subarray

Subarray Sum Equals K

Maximum Size Subarray Sum Equals k

 

參考資料:

https://leetcode.com/problems/subarray-product-less-than-k/

https://leetcode.com/problems/subarray-product-less-than-k/discuss/108830/C%2B%2B-concise-solution-O(n)

https://leetcode.com/problems/subarray-product-less-than-k/discuss/108861/JavaC%2B%2B-Clean-Code-with-Explanation

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM