Applying Prefix Sum Technique in PHP for Efficient Subarray Sum Queries
This article explains the concept of prefix sums, demonstrates how to build and use a prefix‑sum array in PHP with clear code examples, and discusses when the technique is advantageous and its limitations, enabling O(1) interval sum queries after an O(n) preprocessing step.
In PHP development, arrays are a fundamental data structure, and calculating the sum of a sub‑array repeatedly can become inefficient; the prefix‑sum technique solves this by preprocessing the array once so that any range sum can be obtained in constant time.
1. What Is a Prefix Sum?
A prefix sum at index i is the cumulative sum of all elements from the first element up to i . For an original array A = [a₀, a₁, a₂, …, aₙ₋₁] , the prefix‑sum array P = [p₀, p₁, p₂, …, pₙ₋₁] is defined as:
p₀ = a₀
p₁ = a₀ + a₁
p₂ = a₀ + a₁ + a₂
…
pᵢ = pᵢ₋₁ + aᵢ (for i > 0)
2. Why Use Prefix Sums? – Fast Interval Summation
The core benefit is that the sum of any sub‑array A[i…j] can be computed as Sum = P[j] - P[i‑1] (or simply P[j] when i = 0 ), turning a linear‑time loop into a single subtraction.
Key Formulas
Sum(A[i…j]) = P[j] - P[i‑1] (i > 0)
Sum(A[0…j]) = P[j] (i = 0)
Efficiency Comparison
Pre‑processing: building P requires one pass over the original array – O(n).
Query: each interval sum after preprocessing is O(1).
Traditional method: each query costs O(k) where k is the interval length, leading to high total cost for many queries.
3. Step‑by‑Step Guide: Implementing Prefix Sums in PHP
Step 1 – Build the Prefix‑Sum Array
<?php
/**
* Compute the prefix‑sum array for a given numeric array.
* @param array $originalArray Input array.
* @return array Prefix‑sum array (empty if input is empty).
*/
function calculatePrefixSum(array $originalArray): array {
$n = count($originalArray);
if ($n === 0) {
return [];
}
$prefixSum = [];
$prefixSum[0] = $originalArray[0];
for ($i = 1; $i < $n; $i++) {
$prefixSum[$i] = $prefixSum[$i - 1] + $originalArray[$i];
}
return $prefixSum;
}
// Example usage
$data = [1, 3, 5, 2, 4];
$prefixSumArray = calculatePrefixSum($data);
echo "Original array: " . implode(', ', $data) . "\n";
echo "Prefix‑sum array: " . implode(', ', $prefixSumArray) . "\n";
?>Step 2 – Use the Prefix‑Sum Array for Range Queries
<?php
/**
* Get the sum of a range [startIndex, endIndex] using a prefix‑sum array.
* @param array $prefixSum Prefix‑sum array.
* @param int $startIndex Start index (0‑based).
* @param int $endIndex End index (0‑based).
* @param int $originalArraySize Size of the original array for bounds checking.
* @return int|null Sum of the range, or null if indices are invalid.
*/
function getRangeSum(array $prefixSum, int $startIndex, int $endIndex, int $originalArraySize): ?int {
if ($startIndex < 0 || $endIndex >= $originalArraySize || $startIndex > $endIndex) {
trigger_error("Invalid range [$startIndex, $endIndex]", E_USER_WARNING);
return null;
}
if ($startIndex === 0) {
return $prefixSum[$endIndex];
}
return $prefixSum[$endIndex] - $prefixSum[$startIndex - 1];
}
// Full example
$data = [1, 3, 5, 2, 4, 6, 8, 7];
$originalSize = count($data);
$prefixSumArray = calculatePrefixSum($data);
$sum1 = getRangeSum($prefixSumArray, 2, 5, $originalSize); // 5+2+4+6 = 17
$sum2 = getRangeSum($prefixSumArray, 0, 3, $originalSize); // 1+3+5+2 = 11
$sum3 = getRangeSum($prefixSumArray, 4, 4, $originalSize); // 4
$sum4 = getRangeSum($prefixSumArray, 0, $originalSize - 1, $originalSize); // total = 36
$invalidSum = getRangeSum($prefixSumArray, 6, 1, $originalSize); // invalid
echo "Range [2,5] sum: " . ($sum1 ?? 'invalid') . "\n";
echo "Range [0,3] sum: " . ($sum2 ?? 'invalid') . "\n";
echo "Range [4,4] sum: " . ($sum3 ?? 'invalid') . "\n";
echo "Range [0," . ($originalSize - 1) . "] sum: " . ($sum4 ?? 'invalid') . "\n";
echo "Range [6,1] sum: " . ($invalidSum ?? 'invalid') . "\n";
?>4. When to Use Prefix Sums? (Applicable Scenarios & Limitations)
Applicable Scenarios
Frequent interval‑sum queries on a static or rarely‑updated array.
Data‑analysis, algorithm competitions, or large‑scale batch processing where the array does not change often.
Limitations
High update cost – changing an element requires recomputing all subsequent prefix sums (O(n)).
Additional O(n) space is needed for the auxiliary array.
Only works for associative operations like addition; it cannot directly answer range‑max/min queries.
Conclusion
Prefix sums provide a simple yet powerful preprocessing technique that reduces arbitrary sub‑array sum queries from linear to constant time after an O(n) setup, making PHP array operations much more efficient in suitable scenarios while being aware of their update cost and memory overhead.
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.