Subarray Product Less Than K LT713
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
.
Idea 1. Brute force, any subarray nums[i..j] can be represented by a given pair of integers 0 <= i <= j < nums.length.
Time complexity: O(n2)
Space complexity: O(1)
- class Solution {
- public int numSubarrayProductLessThanK(int[] nums, int k) {
- int count = 0;
- for(int i = 0; i < nums.length; ++i) {
- int product = 1;
- for(int j = i; j < nums.length; ++j) {
- product *= nums[j];
- if(product < k) {
- ++count;
- }
- else break;
- }
- }
- return count;
- }
- }
Idea 2. Binary search. Taking advantage:
1. log(x*y) = log(x) + log(y)
2. positive numbers mean monoto increasing for subarray product(or log subarray sum), the prefix product/sum is sorted
reducing subarry product problem to subarray sum problem. For each index i, find the rightmost index j such that prefix[j] - nums[i-1] < Math.log(k). Note the comparison for double, reduce log(k) by 1e-9, to avoid searching the wrong half.
Take nums= {10,3,3,7,2,9,7,4,7,2,8,6,5,1,5}, k = 30 for example,
when searching the subarray {6, 5, 1, 5}, 6* 5 * 1 == 30, if not adding 1e-9, the search will move to {5} because of doble comparison, hence make logK slightly smaller, if the product is equal to k, move to the lower half.
Time complexity: O(nlogn)
Space complexity: O(n)
- class Solution {
- int findMaxIndex(double[] prefix, int left, int right, int k) {
- double logK = Math.log(k);
- int i = left, j = right;
- while(i < j) {
- int mid = i + (j - i) / 2;
- if(prefix[mid] - prefix[left-1] < logK - 1e-9) i = mid + 1;
- else j = mid;
- }
- return i;
- }
- public int numSubarrayProductLessThanK(int[] nums, int k) {
- int count = 0;
- double[] prefix = new double[nums.length + 1];
- for(int i = 1; i < prefix.length; ++i) {
- prefix[i] = prefix[i-1] + Math.log(nums[i-1]);
- }
- for(int i = 1; i < prefix.length; ++i) {
- int maxIndex = findMaxIndex(prefix, i, prefix.length, k);
- count += maxIndex - i;
- }
- return count;
- }
- }
Idea 3. Slicing widnow. Keeping a max-product-windown less than k. Since the elements in the array is positive, the subarray product is a monotone increasing fuction, so we use a sliding window.
Time complexity: O(n)
Space complexity: O(1)
3.a Fixed the left point of a subarray, for each left, find the largest right so that the product of the subarray nums[left] + nums[left+1] + ... + nums[right-1] is less than k. Hence the product of each subarray starting at left and ending at rightEnd (left <= rightEnd < right) is less than k, there are right - left such subarrays. For every left, we update right and prod to maintain the invariant.
Starting with index left ( left = 0), find the first largest right so that the product * nums[right] is larger than k, add right - left to the count.
Shifting the window by moving left to the right by element, update product (product = product/nums[left]), the new subarry will start with index left = left + 1,
if the product*nums[right] is still larger than k, there are right - left subarrys with product less than k; Note: if right == left, it's empty array, no need to update product, product should remain as 1, it means nums[right] > k, we need to move right forward to maintain the invariant left <= right.
otherwise, expand right until product * nums[right] > k, continue the above process until left reaches the end of the array.
Take nums = [10, 5, 2, 100, 6], k = 100 for example,
left = 0, right = 2, product = 100, [10, 5, 2] , there are 2 (right - left) subarrays starting at 0 with product less than 100: [10], [10, 5]
left moving forward, left = 1, product = 100/nums[0] = 10, continue expand right until product = 1000 >= k, right = 3, [5, 2, 100], 2 (right - left) subarrays starting with 5: [5], [5, 2]
left moving forward, left = 2, product = 1000/nums[1] = 200, since product is already larger than k, no need to expand right, keep right= 3, 1 (right - left) subarray starting with 2: [2]
left moving forward, left = 3, right = 3, since left < right, as we define right as the excluded boundary, there is no subarry in the range (right - left) = 0, right is not in the product, we need to move right, right = 4
left moving forward, left = 4, product = 1, 1 * 6 < 100, expanding right = 5, 1 subarray starting with 6, [6]
(10)
(10, 5, 2)
(5, 2, 100)
(2, 100)
(100)
(6)
- class Solution {
- public int numSubarrayProductLessThanK(int[] nums, int k) {
- int count = 0;
- int product = 1;
- for(int left = 0, right = 0; left < nums.length; ++left) {
- for(;right < nums.length && product * nums[right] < k; ++right) {
- product *= nums[right];
- }
- count += right - left;
- if(left < right) {
- product = product/nums[left];
- }
- else {
- ++right;
- }
- }
- return count;
- }
- }
3.b Fix the right point, for each right point, find the smallest left such that the product is less than k.
Shifting the window by adding a new element on the right,
if the product is less than k, then all the subarray nums[left...right] satisfy the requrement, there are right - left + 1 such subarrays ending at index right;
otherwise, shrinking the subarray by moving left index to the right until the subarray product less than k; Note if nums[right] >= k, left will move one step before right, the arry ending at right is empty with right - left + 1 = 0.
(10)
(10, 5)
(5, 2)
(100) right = left + 1, count = 0
(6)
- class Solution {
- public int numSubarrayProductLessThanK(int[] nums, int k) {
- int count = 0;
- int product = 1;
- for(int left = 0, right = 0; right < nums.length; ++right) {
- product *= nums[right];
- while(left <= right && product >= k) {
- product /= nums[left];
- ++left;
- }
- count += right - left + 1;
- }
- return count;
- }
- }
Subarray Product Less Than K LT713的更多相关文章
- [LeetCode] Subarray Product Less Than K 子数组乘积小于K
Your are given an array of positive integers nums. Count and print the number of (contiguous) subarr ...
- [Swift]LeetCode713. 乘积小于K的子数组 | Subarray Product Less Than K
Your are given an array of positive integers nums. Count and print the number of (contiguous) subarr ...
- 713. Subarray Product Less Than K
Your are given an array of positive integers nums. Count and print the number of (contiguous) subarr ...
- LeetCode Subarray Product Less Than K
原题链接在这里:https://leetcode.com/problems/subarray-product-less-than-k/description/ 题目: Your are given a ...
- Subarray Product Less Than K
Your are given an array of positive integers nums. Count and print the number of (contiguous) subarr ...
- leetcode713 Subarray Product Less Than K
""" Your are given an array of positive integers nums. Count and print the number of ...
- 【LeetCode】713. Subarray Product Less Than K 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/subarray ...
- [leetcode] 713. Subarray Product Less Than K
题目 Given an array of integers nums and an integer k, return the number of contiguous subarrays where ...
- LeetCode Subarray Product Less Than K 题解 双指针+单调性
题意 给定一个正整数数组和K,数有多少个连续子数组满足: 数组中所有的元素的积小于K. 思路 依旧是双指针的思路 我们首先固定右指针r. 现在子数组的最右边的元素是nums[r]. 我们让这个子数组尽 ...
随机推荐
- html实现导航栏效果
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- cakePHP 分页栏
<div class="page"><?php if ($total > 1) echo $this->element('page_list', ar ...
- windows上java中文乱码-指定字符集 -Dfile.encoding=UTF-8
jvm启动中增加参数: -Dfile.encoding=UTF-8 重启即可.
- 使用SpirngMvc拦截器实现对登陆用户的身份验证
登陆成功则按returnUrl进行跳转,即跳转到登陆之前的页面,否则跳转到登陆页面,返回登陆错误信息. 1.SpringMVC.xml <!-- 映射器 --> <bean clas ...
- Oracle 入门
一.安装Oracle 11g 服务端 服务端安装教程:https://jingyan.baidu.com/article/363872eccfb9266e4aa16f5d.html 二.安装客户端 客 ...
- web前端开发浏览器兼容性处理大全
1.居中问题 div里的内容,IE默认为居中,而FF默认为左对齐,可以尝试增加代码margin: 0 auto; 2.高度问题 两上下排列或嵌套的div,上面的div设置高度(height),如果di ...
- cloudera cdh5.13.0 vmware 快速安装
1. 从官网上载VMWARE VM快速安装包 https://www.cloudera.com/downloads/quickstart_vms/5-12.html 2. 下载后的安装包,解压之后得到 ...
- 连接SQL常见问题
HTTP Status 500 – Internal Server Error Type Exception Report Message Request processing failed; nes ...
- nodemcu生成LUA版本固件
构建自己的固件地址 https://nodemcu-build.com/
- ngular ionic select ng-options 默认选择第一个值的写法
1. html <select ng-model="selectOrderState" style="border:none;left:0" ng-opt ...