给定一个已排序的数组arr[]和一个具有M 个查询的集合Q ,其中每个查询都有值X和Y ,任务是找到数组中存在的所有小于X和大于Y 的整数的总和。
注意: X 和 Y 可能存在也可能不存在于数组中。
例子:
Input: arr[] = [3 5 8 12 15], Q = {{5, 12}, {4, 8}}
Output:
18
30
Explanation:
For query 1, X = 5 and Y = 12. Sum = 3( < 5) + 15( > 12) = 18.
For query 2, X = 4 and Y = 8. Sum = 3( < 4) + 15 ( > 8) + 12 ( > 8) = 30.
Input: arr[] = [4 7 7 12 15], Q = {{3, 8}, {4, 8}}
Output:
27
27
Explanation:
For query 1, X = 3 and Y = 8. Sum = 12( > 8) + 15 ( > 8) = 27.
For query 2, Sum = 12 + 15 = 27.
方法:
- 构建一个前缀和数组,其中prefix_sum[i]表示arr[0] + arr[1] + … arr[i] 的和。
- 找到值小于X的最后一个索引i并将前缀和提取到第i个索引。可以分别在Python和 C++ 中使用bisect_left()或 lower_bound() 以O(logN)复杂度获得索引。
- 类似地,找到数组中第一个值大于 Y 的索引i并计算和prefix_sum[n-1] – prefix_sum[i-1] 。 Python和 C++ 中的内置函数 bisect() 和 upper_bound() 分别在O(logN) 中执行所需的操作。
- 以上两步计算出的两个结果之和就是要求的答案。对每个查询不断重复这些步骤。
下面是上述方法的实现:
Python3
# Python code for the above program
from bisect import bisect, bisect_left
def createPrefixSum(ar, n):
# Initialize prefix sum
# array
prefix_sum = [0]*n
# Initialize prefix_sum[0]
# by ar[0]
prefix_sum[0] = ar[0]
# Compute prefix sum for
# all indices
for i in range(1, n):
prefix_sum[i] = prefix_sum[i-1]+ar[i]
return prefix_sum
# Function to return sum of all
# elements less than X
def sumLessThanX(ar, x, prefix_xum):
# Index of the last element
# which is less than x
pos_x = bisect_left(ar, x) - 1
if pos_x >= 0 :
return prefix_sum[pos_x]
# If no element is less than x
else:
return 0
# Function to return sum of all
# elements greater than Y
def sumGreaterThanY(ar, y, prefix_sum):
# Index of the first element
# which is greater than y
pos_y = bisect(ar, y)
pos_y -= 1
if pos_y < len(ar)-1 :
return prefix_sum[-1]-prefix_sum[pos_y]
# If no element is greater than y
else:
return 0
def solve(ar, x, y, prefix_sum):
ltx = sumLessThanX(ar, x, prefix_sum)
gty = sumGreaterThanY(ar, y, prefix_sum)
# printing the final sum
print(ltx + gty)
def print_l(lb, ub):
print("sum of integers less than {}".format(lb)
+ " and greater than {} is ".format(ub),
end = '')
if __name__ == '__main__':
# example 1
ar = [3, 6, 6, 12, 15]
n = len(ar)
prefix_sum = createPrefixSum(ar, n)
# for query 1
q1x = 5
q1y = 12
print_l(q1x, q1y)
solve(ar, q1x, q1y, prefix_sum)
# for query 2
q2x = 7
q2y = 8
print_l(q2x, q2y)
solve(ar, q2x, q2y, prefix_sum)
输出:
sum of integers less than 5 and greater than 12 is 18
sum of integers less than 7 and greater than 8 is 42
时间复杂度: O(N + (M * logN))
辅助空间复杂度: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。