Skip to content

Commit 29ce2ef

Browse files
Add RangeSumQuery algorithm in prefix folder (#7280)
* add Subarray Sum Equals K using prefix sum * Add RangeSumQuery algorithm in prefix folder * chore: apply clang-format to RangeSumQueryTest file * Add import statement for JUnit test class --------- Co-authored-by: Deniz Altunkapan <deniz.altunkapan@outlook.com>
1 parent 0a2c7f2 commit 29ce2ef

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-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: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
6+
import org.junit.jupiter.api.Test;
7+
8+
/**
9+
* Tests for {@link RangeSumQuery}.
10+
*/
11+
class RangeSumQueryTest {
12+
13+
@Test
14+
void testBasicExample() {
15+
int[] nums = {1, 2, 3, 4, 5};
16+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
17+
18+
assertEquals(6, RangeSumQuery.sumRange(prefixSum, 0, 2)); // 1+2+3
19+
assertEquals(9, RangeSumQuery.sumRange(prefixSum, 1, 3)); // 2+3+4
20+
assertEquals(15, RangeSumQuery.sumRange(prefixSum, 0, 4)); // 1+2+3+4+5
21+
assertEquals(12, RangeSumQuery.sumRange(prefixSum, 2, 4)); // 3+4+5
22+
}
23+
24+
@Test
25+
void testSingleElement() {
26+
int[] nums = {7};
27+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
28+
29+
assertEquals(7, RangeSumQuery.sumRange(prefixSum, 0, 0));
30+
}
31+
32+
@Test
33+
void testAllZeros() {
34+
int[] nums = {0, 0, 0, 0};
35+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
36+
37+
assertEquals(0, RangeSumQuery.sumRange(prefixSum, 0, 3));
38+
assertEquals(0, RangeSumQuery.sumRange(prefixSum, 1, 2));
39+
}
40+
41+
@Test
42+
void testNegativeNumbers() {
43+
int[] nums = {-1, 2, -3, 4};
44+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
45+
46+
assertEquals(-2, RangeSumQuery.sumRange(prefixSum, 0, 2)); // -1+2-3
47+
assertEquals(3, RangeSumQuery.sumRange(prefixSum, 1, 3)); // 2-3+4
48+
}
49+
50+
@Test
51+
void testEmptyArrayThrowsException() {
52+
int[] nums = {};
53+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
54+
55+
assertThrows(IllegalArgumentException.class, () -> RangeSumQuery.sumRange(prefixSum, 0, 0));
56+
}
57+
58+
@Test
59+
void testNullArrayThrowsException() {
60+
assertThrows(IllegalArgumentException.class, () -> RangeSumQuery.buildPrefixSum(null));
61+
assertThrows(IllegalArgumentException.class, () -> RangeSumQuery.sumRange(null, 0, 0));
62+
}
63+
64+
@Test
65+
void testInvalidIndicesThrowsException() {
66+
int[] nums = {1, 2, 3};
67+
int[] prefixSum = RangeSumQuery.buildPrefixSum(nums);
68+
69+
assertThrows(IllegalArgumentException.class, () -> RangeSumQuery.sumRange(prefixSum, -1, 2));
70+
assertThrows(IllegalArgumentException.class, () -> RangeSumQuery.sumRange(prefixSum, 1, 5));
71+
assertThrows(IllegalArgumentException.class, () -> RangeSumQuery.sumRange(prefixSum, 2, 1));
72+
}
73+
}

0 commit comments

Comments
 (0)