📜  数组中的范围产品查询

📅  最后修改于: 2022-05-13 01:57:52.217000             🧑  作者: Mango

数组中的范围产品查询

我们有一个整数数组和一组范围查询。对于每个查询,我们需要找到给定范围内元素的乘积。
例子:

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)