给定一个正数数组,计算乘积小于给定数K的可能连续子数组的数量。
例子 :
Input : arr[] = [1, 2, 3, 4]
K = 10
Output : 7
The subarrays are {1}, {2}, {3}, {4}
{1, 2}, {1, 2, 3} and {2, 3}
Input : arr[] = [1, 9, 2, 8, 6, 4, 3]
K = 100
Output : 16
Input : arr[] = [10, 5, 2, 6]
K = 100
Output : 8
解决此问题的一种简单方法是生成数组的所有子数组,然后计算乘积大于K的数组的数量。
下面是上述方法的实现:
C++
// CPP program to count subarrays having
// product less than k.
#include
using namespace std;
int countsubarray(int array[], int n, int k)
{
int count = 0;
int i, j, mul;
for (i = 0; i < n; i++) {
// Counter for single element
if (array[i] < k)
count++;
mul = array[i];
for (j = i + 1; j < n; j++) {
// Multiple subarray
mul = mul * array[j];
// If this multiple is less
// than k, then increment
if (mul < k)
count++;
else
break;
}
}
return count;
}
// Driver Code
int main()
{
int array[] = { 1, 2, 3, 4 };
int k = 10;
int size = sizeof(array) / sizeof(array[0]);
int count = countsubarray(array, size, k);
cout << count << "\n";
}
// This code is contributed by 'Dev Agarwal'.
Java
// Java program to count subarrays
// having product less than k.
class GFG {
static int countsubarray(int array[], int n, int k)
{
int count = 0;
int i, j, mul;
for (i = 0; i < n; i++) {
// Counter for single element
if (array[i] < k)
count++;
mul = array[i];
for (j = i + 1; j < n; j++) {
// Multiple subarray
mul = mul * array[j];
// If this multiple is less
// than k, then increment
if (mul < k)
count++;
else
break;
}
}
return count;
}
// Driver Code
public static void main(String args[])
{
int array[] = { 1, 2, 3, 4 };
int k = 10;
int size = array.length;
int count = countsubarray(array, size, k);
System.out.print(count);
}
}
// This code is contributed by Sam007
Python3
# Python3 program to count subarrays
# having product less than k.
def countsubarray(array, n, k):
count = 0
for i in range(0, n):
# Counter for single element
if array[i] < k:
count += 1
mul = array[i]
for j in range(i + 1, n):
# Multiple subarray
mul = mul * array[j]
# If this multiple is less
# than k, then increment
if mul < k:
count += 1
else:
break
return count
# Driver Code
array = [1, 2, 3, 4]
k = 10
size = len(array)
count = countsubarray(array, size, k)
print(count, end=" ")
# This code is contributed by Shreyanshi Arun.
C#
// C# program to count subarrays having
// product less than k.
using System;
public class GFG {
static int countsubarray(int[] array, int n, int k)
{
int count = 0;
int i, j, mul;
for (i = 0; i < n; i++) {
// Counter for single element
if (array[i] < k)
count++;
mul = array[i];
for (j = i + 1; j < n; j++) {
// Multiple subarray
mul = mul * array[j];
// If this multiple is less
// than k, then increment
if (mul < k)
count++;
else
break;
}
}
return count;
}
// Driver Code
static public void Main()
{
int[] array = { 1, 2, 3, 4 };
int k = 10;
int size = array.Length;
int count = countsubarray(array, size, k);
Console.WriteLine(count);
}
}
// This code is contributed by vt_m.
PHP
Javascript
C++
// CPP program to count subarrays having product
// less than k.
#include
#include
using namespace std;
int countSubArrayProductLessThanK(const vector& a,
long long k)
{
const int n = a.size();
long long p = 1;
int res = 0;
for (int start = 0, end = 0; end < n; end++) {
// Move right bound by 1 step. Update the product.
p *= a[end];
// Move left bound so guarantee that p is again
// less than k.
while (start < end && p >= k)
p /= a[start++];
// If p is less than k, update the counter.
// Note that this is working even for (start ==
// end): it means that the previous window cannot
// grow anymore and a single array element is the
// only addendum.
if (p < k) {
int len = end - start + 1;
res += len;
}
}
return res;
}
// Driver Code
int main()
{
// Function Calls
cout << countSubArrayProductLessThanK({ 1, 2, 3, 4 },
10)
<< endl;
cout << countSubArrayProductLessThanK(
{ 1, 9, 2, 8, 6, 4, 3 }, 100)
<< endl;
cout << countSubArrayProductLessThanK({ 5, 3, 2 }, 16)
<< endl;
cout << countSubArrayProductLessThanK({ 100, 200 }, 100)
<< endl;
cout << countSubArrayProductLessThanK({ 100, 200 }, 101)
<< endl;
}
Java
// Java program to count subarrays having
// product less than k.
import java.util.*;
class GFG {
static int
countSubArrayProductLessThanK(ArrayList a,
long k)
{
int n = a.size();
long p = 1;
int res = 0;
for (int start = 0, end = 0; end < n; end++) {
// Move right bound by 1 step.
// Update the product.
p *= a.get(end);
// Move left bound so guarantee that
// p is again less than k.
while (start < end && p >= k)
p /= a.get(start++);
// If p is less than k, update the counter.
// Note that this is working even for
// (start == end): it means that the
// previous window cannot grow anymore
// and a single array element is the only
// addendum.
if (p < k) {
int len = end - start + 1;
res += len;
}
}
return res;
}
// Drive Code
public static void main(String[] args)
{
// Function Calls
ArrayList al = new ArrayList();
al.add(1);
al.add(2);
al.add(3);
al.add(4);
System.out.println(
countSubArrayProductLessThanK(al, 10));
ArrayList al1 = new ArrayList();
al1.add(1);
al1.add(9);
al1.add(2);
al1.add(8);
al1.add(6);
al1.add(4);
al1.add(3);
System.out.println(
countSubArrayProductLessThanK(al1, 100));
ArrayList al2 = new ArrayList();
al2.add(5);
al2.add(3);
al2.add(2);
System.out.println(
countSubArrayProductLessThanK(al2, 16));
ArrayList al3 = new ArrayList();
al3.add(100);
al3.add(200);
System.out.println(
countSubArrayProductLessThanK(al3, 100));
ArrayList al4 = new ArrayList();
al4.add(100);
al4.add(200);
System.out.println(
countSubArrayProductLessThanK(al3, 101));
}
}
// This code is contributed by Prerna Saini
Python3
# Python3 program to count
# subarrays having product
# less than k.
def countSubArrayProductLessThanK(a, k):
n = len(a)
p = 1
res = 0
start = 0
end = 0
while(end < n):
# Move right bound by 1
# step. Update the product.
p *= a[end]
# Move left bound so guarantee
# that p is again less than k.
while (start < end and p >= k):
p = int(p//a[start])
start += 1
# If p is less than k, update
# the counter. Note that this
# is working even for (start == end):
# it means that the previous
# window cannot grow anymore
# and a single array element
# is the only addendum.
if (p < k):
l = end - start + 1
res += l
end += 1
return res
# Driver Code
if __name__ == '__main__':
print(countSubArrayProductLessThanK([1, 2, 3, 4], 10))
print(countSubArrayProductLessThanK([1, 9, 2, 8, 6, 4, 3], 100))
print(countSubArrayProductLessThanK([5, 3, 2], 16))
print(countSubArrayProductLessThanK([100, 200], 100))
print(countSubArrayProductLessThanK([100, 200], 101))
# This code is contributed by mits
C#
// C# program to count subarrays
// having product less than k.
using System;
using System.Collections;
class GFG {
static int countSubArrayProductLessThanK(ArrayList a,
int k)
{
int n = a.Count;
int p = 1;
int res = 0;
for (int start = 0, end = 0; end < n; end++) {
// Move right bound by 1 step.
// Update the product.
p *= (int)a[end];
// Move left bound so guarantee
// that p is again less than k.
while (start < end && p >= k)
p /= (int)a[start++];
// If p is less than k, update the
// counter. Note that this is working
// even for (start == end): it means
// that the previous window cannot
// grow anymore and a single array
// element is the only Addendum.
if (p < k) {
int len = end - start + 1;
res += len;
}
}
return res;
}
// Driver Code
static void Main()
{
ArrayList al = new ArrayList();
al.Add(1);
al.Add(2);
al.Add(3);
al.Add(4);
Console.WriteLine(
countSubArrayProductLessThanK(al, 10));
ArrayList al1 = new ArrayList();
al1.Add(1);
al1.Add(9);
al1.Add(2);
al1.Add(8);
al1.Add(6);
al1.Add(4);
al1.Add(3);
Console.WriteLine(
countSubArrayProductLessThanK(al1, 100));
ArrayList al2 = new ArrayList();
al2.Add(5);
al2.Add(3);
al2.Add(2);
Console.WriteLine(
countSubArrayProductLessThanK(al2, 16));
ArrayList al3 = new ArrayList();
al3.Add(100);
al3.Add(200);
Console.WriteLine(
countSubArrayProductLessThanK(al3, 100));
ArrayList al4 = new ArrayList();
al4.Add(100);
al4.Add(200);
Console.WriteLine(
countSubArrayProductLessThanK(al3, 101));
}
}
// This code is contributed by mits
PHP
= $k)
$p /= $a[$start++];
// If p is less than k, update
// the counter. Note that this
// is working even for (start == end):
// it means that the previous
// window cannot grow anymore
// and a single array element
// is the only addendum.
if ($p < $k)
{
$len = $end - $start + 1;
$res += $len;
}
}
return $res;
}
// Driver Code
echo countSubArrayProductLessThanK(
array(1, 2, 3, 4), 10) . "\n";
echo countSubArrayProductLessThanK(
array(1, 9, 2, 8, 6, 4, 3), 100) . "\n";
echo countSubArrayProductLessThanK(
array(5, 3, 2), 16) . "\n";
echo countSubArrayProductLessThanK(
array(100, 200), 100) . "\n";
echo countSubArrayProductLessThanK(
array(100, 200), 101) . "\n";
// This code is contributed by mits
?>
7
时间复杂度: O(n ^ 2)。
我们可以基于滑动窗口技术来优化方法(注意,我们需要找到连续的部分)
首先,根据描述,数组中的所有元素都严格为正。还要假设所有数组元素的乘积始终适合64位整数类型。考虑到这两点,我们能够对数组元素的安全性进行乘除(无零除法,无溢出)。
让我们看看如何计算所需的金额。假设我们在开始和结束之间有一个窗口,并且所有元素的乘积为p 情况1. p * x 情况2. p * x> = k 例子 : 输出 : 复杂度:数组中的每个元素最多可访问两次,因此,这是O(n)时间复杂度。使用了几个标量变量,因此,它是O(1)多余的空间。 练习1:更新解决方案,以便它可以处理输入数组中的nil。
这意味着我们可以将窗口的右边界再移一步。此步骤会产生多少个连续数组?它是:1 +(结束开始)。
实际上,元素本身包含一个数组,我们也可以将x添加到所有具有右边界的连续数组中。这样的数组与窗口的长度一样多。
这意味着我们必须首先调整窗口的左边框,以使乘积再次小于k。之后,我们可以应用案例1中的公式。a = [5, 3, 2]
k = 16
counter = 0
Window: [5]
Product: 5
5 counter += 1+ (0-0)
counter = 1
Window: [5,3]
Product: 15
15 counter += 1 + (1-0)
counter = 3
Window: [5,3,2]
Product: 30
30 > 16 --> Adjust the left border
New Window: [3,2]
New Product: 6
6 counter += 1 + (2-1)
counter = 5
Answer: 5
C++
// CPP program to count subarrays having product
// less than k.
#include
Java
// Java program to count subarrays having
// product less than k.
import java.util.*;
class GFG {
static int
countSubArrayProductLessThanK(ArrayList
Python3
# Python3 program to count
# subarrays having product
# less than k.
def countSubArrayProductLessThanK(a, k):
n = len(a)
p = 1
res = 0
start = 0
end = 0
while(end < n):
# Move right bound by 1
# step. Update the product.
p *= a[end]
# Move left bound so guarantee
# that p is again less than k.
while (start < end and p >= k):
p = int(p//a[start])
start += 1
# If p is less than k, update
# the counter. Note that this
# is working even for (start == end):
# it means that the previous
# window cannot grow anymore
# and a single array element
# is the only addendum.
if (p < k):
l = end - start + 1
res += l
end += 1
return res
# Driver Code
if __name__ == '__main__':
print(countSubArrayProductLessThanK([1, 2, 3, 4], 10))
print(countSubArrayProductLessThanK([1, 9, 2, 8, 6, 4, 3], 100))
print(countSubArrayProductLessThanK([5, 3, 2], 16))
print(countSubArrayProductLessThanK([100, 200], 100))
print(countSubArrayProductLessThanK([100, 200], 101))
# This code is contributed by mits
C#
// C# program to count subarrays
// having product less than k.
using System;
using System.Collections;
class GFG {
static int countSubArrayProductLessThanK(ArrayList a,
int k)
{
int n = a.Count;
int p = 1;
int res = 0;
for (int start = 0, end = 0; end < n; end++) {
// Move right bound by 1 step.
// Update the product.
p *= (int)a[end];
// Move left bound so guarantee
// that p is again less than k.
while (start < end && p >= k)
p /= (int)a[start++];
// If p is less than k, update the
// counter. Note that this is working
// even for (start == end): it means
// that the previous window cannot
// grow anymore and a single array
// element is the only Addendum.
if (p < k) {
int len = end - start + 1;
res += len;
}
}
return res;
}
// Driver Code
static void Main()
{
ArrayList al = new ArrayList();
al.Add(1);
al.Add(2);
al.Add(3);
al.Add(4);
Console.WriteLine(
countSubArrayProductLessThanK(al, 10));
ArrayList al1 = new ArrayList();
al1.Add(1);
al1.Add(9);
al1.Add(2);
al1.Add(8);
al1.Add(6);
al1.Add(4);
al1.Add(3);
Console.WriteLine(
countSubArrayProductLessThanK(al1, 100));
ArrayList al2 = new ArrayList();
al2.Add(5);
al2.Add(3);
al2.Add(2);
Console.WriteLine(
countSubArrayProductLessThanK(al2, 16));
ArrayList al3 = new ArrayList();
al3.Add(100);
al3.Add(200);
Console.WriteLine(
countSubArrayProductLessThanK(al3, 100));
ArrayList al4 = new ArrayList();
al4.Add(100);
al4.Add(200);
Console.WriteLine(
countSubArrayProductLessThanK(al3, 101));
}
}
// This code is contributed by mits
的PHP
= $k)
$p /= $a[$start++];
// If p is less than k, update
// the counter. Note that this
// is working even for (start == end):
// it means that the previous
// window cannot grow anymore
// and a single array element
// is the only addendum.
if ($p < $k)
{
$len = $end - $start + 1;
$res += $len;
}
}
return $res;
}
// Driver Code
echo countSubArrayProductLessThanK(
array(1, 2, 3, 4), 10) . "\n";
echo countSubArrayProductLessThanK(
array(1, 9, 2, 8, 6, 4, 3), 100) . "\n";
echo countSubArrayProductLessThanK(
array(5, 3, 2), 16) . "\n";
echo countSubArrayProductLessThanK(
array(100, 200), 100) . "\n";
echo countSubArrayProductLessThanK(
array(100, 200), 101) . "\n";
// This code is contributed by mits
?>
7
16
5
0
1
练习2:更新解决方案,以便在计算乘积时可以处理乘法溢出。