Skip to content

Commit 6cb76bd

Browse files
Add RangeSumQuery algorithm in prefix folder
1 parent 964175f commit 6cb76bd

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.thealgorithms.prefixsum;
2+
3+
/**
4+
* Implements an algorithm to efficiently compute the sum of elements
5+
* between any two indices in an integer array using the Prefix Sum technique.
6+
*
7+
* <p>
8+
* Given an array nums, this algorithm precomputes the prefix sum array
9+
* to allow O(1) sum queries for any range [left, right].
10+
* </p>
11+
*
12+
* <p>
13+
* Let prefixSum[i] be the sum of elements from index 0 to i-1.
14+
* The sum of elements from left to right is:
15+
*
16+
* <pre>
17+
* prefixSum[right + 1] - prefixSum[left]
18+
* </pre>
19+
* </p>
20+
*
21+
* <p>
22+
* <strong>Time Complexity:</strong> O(N) for preprocessing, O(1) per query<br>
23+
* <strong>Space Complexity:</strong> O(N)
24+
* </p>
25+
*
26+
* @author Ruturaj Jadhav, <a href="https://github.com/ruturajjadhav07">ruturajjadhav07</a>
27+
*/
28+
public final class RangeSumQuery {
29+
30+
private RangeSumQuery() {
31+
// Utility class; prevent instantiation
32+
}
33+
34+
/**
35+
* Computes the prefix sum array for efficient range queries.
36+
*
37+
* @param nums The input integer array.
38+
* @return Prefix sum array where prefixSum[i+1] = sum of nums[0..i].
39+
* @throws IllegalArgumentException if nums is null.
40+
*/
41+
public static int[] buildPrefixSum(int[] nums) {
42+
if (nums == null) {
43+
throw new IllegalArgumentException("Input array cannot be null");
44+
}
45+
46+
int n = nums.length;
47+
int[] prefixSum = new int[n + 1];
48+
for (int i = 0; i < n; i++) {
49+
prefixSum[i + 1] = prefixSum[i] + nums[i];
50+
}
51+
return prefixSum;
52+
}
53+
54+
/**
55+
* Returns the sum of elements from index left to right (inclusive)
56+
* using the provided prefix sum array.
57+
*
58+
* @param prefixSum The prefix sum array computed using buildPrefixSum.
59+
* @param left The start index (inclusive).
60+
* @param right The end index (inclusive).
61+
* @return The sum of elements in the range [left, right].
62+
* @throws IllegalArgumentException if indices are invalid.
63+
*/
64+
public static int sumRange(int[] prefixSum, int left, int right) {
65+
if (prefixSum == null) {
66+
throw new IllegalArgumentException("Prefix sum array cannot be null");
67+
}
68+
if (left < 0 || right >= prefixSum.length - 1 || left > right) {
69+
throw new IllegalArgumentException("Invalid range indices");
70+
}
71+
return prefixSum[right + 1] - prefixSum[left];
72+
}
73+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.thealgorithms.prefixsum;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
import org.junit.jupiter.api.Test;
6+
7+
/**
8+
* Tests for {@link RangeSumQuery}.
9+
*/
10+
class RangeSumQueryTest {
11+
12+
@Test
13+
void testBasicExample() {
14+
int[] nums = {1, 2, 3, 4, 5};
15+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
16+
17+
assertEquals(6, RangeSumQuery.sumRange(prefixSum, 0, 2)); // 1+2+3
18+
assertEquals(9, RangeSumQuery.sumRange(prefixSum, 1, 3)); // 2+3+4
19+
assertEquals(15, RangeSumQuery.sumRange(prefixSum, 0, 4)); // 1+2+3+4+5
20+
assertEquals(12, RangeSumQuery.sumRange(prefixSum, 2, 4)); // 3+4+5
21+
}
22+
23+
@Test
24+
void testSingleElement() {
25+
int[] nums = {7};
26+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
27+
28+
assertEquals(7, RangeSumQuery.sumRange(prefixSum, 0, 0));
29+
}
30+
31+
@Test
32+
void testAllZeros() {
33+
int[] nums = {0, 0, 0, 0};
34+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
35+
36+
assertEquals(0, RangeSumQuery.sumRange(prefixSum, 0, 3));
37+
assertEquals(0, RangeSumQuery.sumRange(prefixSum, 1, 2));
38+
}
39+
40+
@Test
41+
void testNegativeNumbers() {
42+
int[] nums = {-1, 2, -3, 4};
43+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
44+
45+
assertEquals(-2, RangeSumQuery.sumRange(prefixSum, 0, 2)); // -1+2-3
46+
assertEquals(3, RangeSumQuery.sumRange(prefixSum, 1, 3)); // 2-3+4
47+
}
48+
49+
@Test
50+
void testEmptyArrayThrowsException() {
51+
int[] nums = {};
52+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
53+
54+
assertThrows(IllegalArgumentException.class,
55+
() -> RangeSumQuery.sumRange(prefixSum, 0, 0));
56+
}
57+
58+
@Test
59+
void testNullArrayThrowsException() {
60+
assertThrows(IllegalArgumentException.class,
61+
() -> RangeSumQuery.buildPrefixSum(null));
62+
assertThrows(IllegalArgumentException.class,
63+
() -> RangeSumQuery.sumRange(null, 0, 0));
64+
}
65+
66+
@Test
67+
void testInvalidIndicesThrowsException() {
68+
int[] nums = {1, 2, 3};
69+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
70+
71+
assertThrows(IllegalArgumentException.class,
72+
() -> RangeSumQuery.sumRange(prefixSum, -1, 2));
73+
assertThrows(IllegalArgumentException.class,
74+
() -> RangeSumQuery.sumRange(prefixSum, 1, 5));
75+
assertThrows(IllegalArgumentException.class,
76+
() -> RangeSumQuery.sumRange(prefixSum, 2, 1));
77+
}
78+
}

0 commit comments

Comments
 (0)