📜  没有更新的范围求和查询

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

没有更新的范围求和查询

给定一个大小为 n 的整数数组 arr。我们需要计算从索引 i 到索引 j 的元素之和。由 i 和 j 索引值组成的查询将被执行多次。

例子:

Input : arr[] = {1, 2, 3, 4, 5}
        i = 1, j = 3
        i = 2, j = 4
Output :  9
         12         

Input : arr[] = {1, 2, 3, 4, 5}
        i = 0, j = 4 
        i = 1, j = 2 
Output : 15
          5

一个简单的解决方案是计算每个查询的总和。

一个有效的解决方案是预先计算前缀和。让 pre[i] 存储从 arr[0] 到 arr[i] 的元素总和。为了回答查询 (i, j),我们返回 pre[j] – pre[i-1]。

下面是上述方法的实现:

C++
// CPP program to find sum between two indexes
// when there is no update.
#include 
using namespace std;
 
void preCompute(int arr[], int n, int pre[])
{
    pre[0] = arr[0];
    for (int i = 1; i < n; i++)
        pre[i] = arr[i] + pre[i - 1];
}
 
// Returns sum of elements in arr[i..j]
// It is assumed that i <= j
int rangeSum(int i, int j, int pre[])
{
    if (i == 0)
        return pre[j];
 
    return pre[j] - pre[i - 1];
}
 
// Driver code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int pre[n];
   
    // Function call
    preCompute(arr, n, pre);
    cout << rangeSum(1, 3, pre) << endl;
    cout << rangeSum(2, 4, pre) << endl;
 
    return 0;
}


Java
// Java program to find sum between two indexes
// when there is no update.
 
import java.util.*;
import java.lang.*;
 
class GFG {
    public static void preCompute(int arr[], int n,
                                  int pre[])
    {
        pre[0] = arr[0];
        for (int i = 1; i < n; i++)
            pre[i] = arr[i] + pre[i - 1];
    }
 
    // Returns sum of elements in arr[i..j]
    // It is assumed that i <= j
    public static int rangeSum(int i, int j, int pre[])
    {
        if (i == 0)
            return pre[j];
 
        return pre[j] - pre[i - 1];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 3, 4, 5 };
        int n = arr.length;
 
        int pre[] = new int[n];
 
        preCompute(arr, n, pre);
        System.out.println(rangeSum(1, 3, pre));
        System.out.println(rangeSum(2, 4, pre));
    }
}
 
// Code Contributed by Mohit Gupta_OMG <(0_o)>


Python3
# Python program to find sum between two indexes
# when there is no update.
 
# Function to compute prefix sum
def preCompute(arr, n, prefix):
  prefix[0] = arr[0]
  for i in range(1, n):
    prefix[i] = prefix[i - 1] + arr[i]
 
# Returns sum of elements in arr[i..j]
# It is assumed that i <= j
def rangeSum(l, r):
  if l == 0:
    print(prefix[r])
    return
   
  print(prefix[r] - prefix[l - 1])
     
# Driver code
arr = [1, 2, 3, 4, 5]
n = len(arr)
prefix = [0 for i in range(n)]
 
# preComputation
preCompute(arr, n, prefix)
 
# Range Queries
rangeSum(1, 3)
rangeSum(2, 4)
 
# This code is contributed by dineshdkda31.


C#
// Program to find sum between two
// indexes when there is no update.
using System;
 
class GFG {
    public static void preCompute(int[] arr, int n,
                                  int[] pre)
    {
        pre[0] = arr[0];
        for (int i = 1; i < n; i++)
            pre[i] = arr[i] + pre[i - 1];
    }
 
    // Returns sum of elements in
    // arr[i..j]
    // It is assumed that i <= j
    public static int rangeSum(int i, int j, int[] pre)
    {
        if (i == 0)
            return pre[j];
 
        return pre[j] - pre[i - 1];
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { 1, 2, 3, 4, 5 };
        int n = arr.Length;
 
        int[] pre = new int[n];
 
        // Function call
        preCompute(arr, n, pre);
        Console.WriteLine(rangeSum(1, 3, pre));
        Console.WriteLine(rangeSum(2, 4, pre));
    }
}
 
// Code Contributed by Anant Agarwal.


Javascript


输出
9
12

这里每个范围求和查询的时间复杂度为 O(1),整体时间复杂度为 O(n)。

当也允许更新时,问题变得复杂。在这种情况下,当使用高级数据结构(如段树或二进制索引树)时。