没有更新的范围求和查询
给定一个大小为 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)。
当也允许更新时,问题变得复杂。在这种情况下,当使用高级数据结构(如段树或二进制索引树)时。