数组中的范围产品查询
我们有一个整数数组和一组范围查询。对于每个查询,我们需要找到给定范围内元素的乘积。
例子:
Input : arr[] = {5, 10, 15, 20, 25}
queries[] = {(3, 5), (2, 2), (2, 3)}
Output : 7500, 10, 150
7500 = 15 x 20 x 25
10 = 10
150 = 10 x 15
一种天真的方法是从下到上浏览数组中的每个元素,然后将所有元素相乘以找到乘积。每个查询的时间复杂度为 O(n)。
一种有效的方法是采用另一个数组并将所有元素的乘积存储到数组的第 i 个索引中索引为 i 的元素。但这里有一个问题。如果数组中的任何元素为 0,则 dp 数组将从那时起包含 0。因此,即使 0 不在上下限之间的范围内,我们也应该得到 0 作为我们的答案。
为了解决这种情况,我们使用了另一个名为 countZeros 的数组,它将包含数组包含的直到索引 i 的 '0' 的数量。
现在如果countZeros[upper]-countZeros[lower] > 0 ,则表示该范围内有一个 0,因此答案将为 0。否则我们将相应地继续。
C++
// C++ program for array
// range product queries
#include
using namespace std;
// Answers product queries
// given as two arrays
// lower[] and upper[].
void findProduct(long arr[], int lower[],
int upper[], int n, int n1)
{
long preProd[n];
int countZeros[n];
long prod = 1; // stores the product
// keeps count of zeros
int count = 0;
for (int i = 0; i < n; i++)
{
// if arr[i] is 0, we increment
// count and do not multiply
// it with the product
if (arr[i] == 0)
count++;
else
prod *= arr[i];
// store the value of prod in dp
preProd[i] = prod;
// store the value of
// count in countZeros
countZeros[i] = count;
}
// We have preprocessed
// the array, let us
// answer queries now.
for (int i = 0; i < n1; i++)
{
int l = lower[i];
int u = upper[i];
// range starts from
// first element
if (l == 1)
{
// range does not
// contain any zero
if (countZeros[u - 1] == 0)
cout << (preProd[u - 1]) << endl;
else
cout<<0<
Java
// Java program for array range product queries
class Product {
// Answers product queries given as two arrays
// lower[] and upper[].
static void findProduct(long[] arr, int[] lower,
int[] upper)
{
int n = arr.length;
long[] preProd = new long[n];
int[] countZeros = new int[n];
long prod = 1; // stores the product
// keeps count of zeros
int count = 0;
for (int i = 0; i < n; i++) {
// if arr[i] is 0, we increment count and
// do not multiply it with the product
if (arr[i] == 0)
count++;
else
prod *= arr[i];
// store the value of prod in dp
preProd[i] = prod;
// store the value of count in countZeros
countZeros[i] = count;
}
// We have preprocessed the array, let us
// answer queries now.
for (int i = 0; i < lower.length; i++) {
int l = lower[i];
int u = upper[i];
// range starts from first element
if (l == 1)
{
// range does not contain any zero
if (countZeros[u - 1] == 0)
System.out.println(preProd[u - 1]);
else
System.out.println(0);
}
else // range starts from any other index
{
// no difference in countZeros indicates that
// there are no zeros in the range
if (countZeros[u - 1] - countZeros[l - 2] == 0)
System.out.println(preProd[u - 1] / preProd[l - 2]);
else // zeros are present in the range
System.out.println(0);
}
}
}
public static void main(String[] args)
{
long[] arr = new long[] { 0, 2, 3, 4, 5 };
int[] lower = {1, 2};
int[] upper = {3, 2};
findProduct(arr, lower, upper);
}
}
Python3
# Python 3 program for array range
# product queries
# Answers product queries given as
# lower[] and upper[].
def findProduct(arr,lower, upper, n, n1):
preProd = [0 for i in range(n)]
countZeros = [0 for i in range(n)]
prod = 1
# stores the product
# keeps count of zeros
count = 0
for i in range(0, n, 1):
# if arr[i] is 0, we increment
# count and do not multiply
# it with the product
if (arr[i] == 0):
count += 1
else:
prod *= arr[i]
# store the value of prod in dp
preProd[i] = prod
# store the value of count
# in countZeros
countZeros[i] = count
# We have preprocessed the array,
# let us answer queries now.
for i in range(0, n1, 1):
l = lower[i]
u = upper[i]
# range starts from first element
if (l == 1):
# range does not contain any zero
if (countZeros[u - 1] == 0):
print(int(preProd[u - 1]))
else:
print(0)
else:
# range starts from any other index
# no difference in countZeros indicates
# that there are no zeros in the range
if (countZeros[u - 1] -
countZeros[l - 2] == 0):
print(int(preProd[u - 1] /
preProd[l - 2]))
else:
# zeros are present in the range
print(0)
# Driver code
if __name__ == '__main__':
arr = [0, 2, 3, 4, 5]
lower = [1, 2]
upper = [3, 2]
findProduct(arr, lower, upper,5, 2)
# This code is contributed by
# Sahil_Shelangia
C#
// C# program for array
// range product queries
using System;
class GFG
{
// Answers product queries
// given as two arrays
// lower[] and upper[].
static void findProduct(long[] arr,
int[] lower,
int[] upper)
{
int n = arr.Length;
long[] preProd = new long[n];
int[] countZeros = new int[n];
long prod = 1; // stores the product
// keeps count of zeros
int count = 0;
for (int i = 0; i < n; i++)
{
// if arr[i] is 0, we increment
// count and do not multiply it
// with the product
if (arr[i] == 0)
count++;
else
prod *= arr[i];
// store the value
// of prod in dp
preProd[i] = prod;
// store the value of
// count in countZeros
countZeros[i] = count;
}
// We have preprocessed
// the array, let us
// answer queries now.
for (int i = 0;
i < lower.Length; i++)
{
int l = lower[i];
int u = upper[i];
// range starts from
// first element
if (l == 1)
{
// range does not
// contain any zero
if (countZeros[u - 1] == 0)
Console.WriteLine(preProd[u - 1]);
else
Console.WriteLine(0);
}
// range starts from
// any other index
else
{
// no difference in countZeros
// indicates that there are no
// zeros in the range
if (countZeros[u - 1] -
countZeros[l - 2] == 0)
Console.WriteLine(preProd[u - 1] /
preProd[l - 2]);
// zeros are present
// in the range
else
Console.WriteLine(0);
}
}
}
// Driver Code
public static void Main()
{
long[] arr = {0, 2, 3, 4, 5};
int[] lower = {1, 2};
int[] upper = {3, 2};
findProduct(arr, lower, upper);
}
}
// This code is contributed
// by chandan_jnu.
PHP
Javascript
输出:
0
2
时间复杂度:在创建 dp 数组期间O(n)和每个查询O(1)