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.

class Solution {
public:
    int numSubarrayProductLessThanK(vector<int>& nums, int k) {
        int cnt = 0;
        int multi = 1;
        queue<int> que;
        for(int i=0; i<nums.size(); i++)
        {
            while(nums[i]*multi>=k&&que.size())
            {
                multi/=que.front();
                que.pop();
            }
            
            if(nums[i]*multi<k)
            {
                multi *= nums[i];
                que.push(nums[i]);
            }
            
            cnt += que.size();
        }
        
        return cnt;
    }
};


### 子数组相关算法与概念 子数组(subarray)是指从一个数组中连续选取的一部分元素。在编程和算法设计中,子数组相关的算法通常涉及寻找满足特定条件的最大或最小子数组、计算子数组的和等操作。以下是几个常见的子数组相关算法及其概念: #### 1. 最大子数组问题 最大子数组问题旨在找到一个数组中的连续子数组,使其元素之和最大。动态规划是一种常用的解决方法[^3]。例如,Kadane算法可以高效地解决这一问题,其核心思想是通过维护当前子数组的最大和以及全局最大和来逐步更新结果。 ```python def max_subarray(nums): current_sum = max_sum = nums[0] for num in nums[1:]: current_sum = max(num, current_sum + num) max_sum = max(max_sum, current_sum) return max_sum ``` #### 2. 滑动窗口技术 滑动窗口是一种用于处理子数组问题的有效技术,尤其适用于需要在固定大小的窗口内进行计算的情况。例如,给定一个数组和一个整数 `k`,要求找到所有长度为 `k` 的子数组的平均值,可以使用滑动窗口来避免重复计算。 ```python def find_averages_of_subarrays(k, arr): result = [] window_sum, window_start = 0, 0 for window_end in range(len(arr)): window_sum += arr[window_end] if window_end >= k - 1: result.append(window_sum / k) window_sum -= arr[window_start] window_start += 1 return result ``` #### 3. 动态规划与子数组 动态规划的核心在于将复杂问题分解为更简单的子问题,并存储这些子问题的解以避免重复计算[^3]。例如,在求解最长递增子数组时,可以定义状态 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子数组的长度。 ```python def length_of_lis(nums): if not nums: return 0 dp = [1] * len(nums) for i in range(1, len(nums)): for j in range(i): if nums[i] > nums[j]: dp[i] = max(dp[i], dp[j] + 1) return max(dp) ``` #### 4. 分治法与子数组 分治法通过将问题划分为多个独立的子问题来解决[^2]。然而,在某些情况下,子数组问题可能需要考虑跨越中间点的子数组。例如,在求解最大子数组问题时,可以通过递归地分割数组并计算左半部分、右半部分以及跨越中间点的最大子数组来得到最终结果。 ```python def max_crossing_subarray(arr, low, mid, high): left_sum = float('-inf') sum = 0 max_left = mid for i in range(mid, low - 1, -1): sum += arr[i] if sum > left_sum: left_sum = sum max_left = i right_sum = float('-inf') sum = 0 max_right = mid + 1 for j in range(mid + 1, high + 1): sum += arr[j] if sum > right_sum: right_sum = sum max_right = j return (max_left, max_right, left_sum + right_sum) def max_subarray_divide_and_conquer(arr, low, high): if high == low: return (low, high, arr[low]) else: mid = (low + high) // 2 left_low, left_high, left_sum = max_subarray_divide_and_conquer(arr, low, mid) right_low, right_high, right_sum = max_subarray_divide_and_conquer(arr, mid + 1, high) cross_low, cross_high, cross_sum = max_crossing_subarray(arr, low, mid, high) if left_sum >= right_sum and left_sum >= cross_sum: return (left_low, left_high, left_sum) elif right_sum >= left_sum and right_sum >= cross_sum: return (right_low, right_high, right_sum) else: return (cross_low, cross_high, cross_sum) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值