💡 This approach introduces prefix sums to avoid repeated summations, teaching how to precompute and reuse information efficiently.
Intuition
Precompute prefix sums so that left and right sums can be found in O(1) time for each index, reducing overall complexity.
Algorithm
- Compute prefix sums array where prefix[i] is sum of nums[0..i-1].
- Iterate over each index i.
- Calculate left sum as prefix[i].
- Calculate right sum as prefix[n] - prefix[i+1].
- If left sum equals right sum, return i.
💡 The key insight is using prefix sums to get sums instantly, avoiding nested loops.
def pivotIndex(nums):
n = len(nums)
prefix = [0] * (n + 1)
for i in range(n):
prefix[i+1] = prefix[i] + nums[i]
for i in range(n):
left_sum = prefix[i]
right_sum = prefix[n] - prefix[i+1]
if left_sum == right_sum:
return i
return -1
# Driver code
if __name__ == '__main__':
print(pivotIndex([1,7,3,6,5,6])) # Output: 3
print(pivotIndex([2,1,-1])) # Output: 0
Line Notes
prefix = [0] * (n + 1)Initialize prefix sums array with extra space for zero prefix
prefix[i+1] = prefix[i] + nums[i]Build prefix sums cumulatively
left_sum = prefix[i]Left sum is sum of elements before i
right_sum = prefix[n] - prefix[i+1]Right sum is total sum minus prefix sum up to index i inclusive
return -1Return -1 if no pivot index found
public class Solution {
public static int pivotIndex(int[] nums) {
int n = nums.length;
int[] prefix = new int[n + 1];
for (int i = 0; i < n; i++) {
prefix[i + 1] = prefix[i] + nums[i];
}
for (int i = 0; i < n; i++) {
int leftSum = prefix[i];
int rightSum = prefix[n] - prefix[i + 1];
if (leftSum == rightSum) return i;
}
return -1;
}
public static void main(String[] args) {
System.out.println(pivotIndex(new int[]{1,7,3,6,5,6})); // Output: 3
System.out.println(pivotIndex(new int[]{2,1,-1})); // Output: 0
}
}
Line Notes
int[] prefix = new int[n + 1];Create prefix sums array with one extra element
prefix[i + 1] = prefix[i] + nums[i];Compute cumulative sums
int leftSum = prefix[i];Left sum is prefix sum before index i
int rightSum = prefix[n] - prefix[i + 1];Right sum is total sum minus prefix sum up to index i inclusive
return -1;Return -1 if no pivot index found
#include <iostream>
#include <vector>
using namespace std;
int pivotIndex(vector<int>& nums) {
int n = nums.size();
vector<int> prefix(n + 1, 0);
for (int i = 0; i < n; i++) {
prefix[i + 1] = prefix[i] + nums[i];
}
for (int i = 0; i < n; i++) {
int leftSum = prefix[i];
int rightSum = prefix[n] - prefix[i + 1];
if (leftSum == rightSum) return i;
}
return -1;
}
int main() {
vector<int> nums = {1,7,3,6,5,6};
cout << pivotIndex(nums) << endl; // Output: 3
vector<int> test = {2,1,-1};
cout << pivotIndex(test) << endl; // Output: 0
return 0;
}
Line Notes
vector<int> prefix(n + 1, 0);Initialize prefix sums vector with zeros
prefix[i + 1] = prefix[i] + nums[i];Build prefix sums cumulatively
int leftSum = prefix[i];Left sum is prefix sum before current index
int rightSum = prefix[n] - prefix[i + 1];Right sum is total sum minus prefix sum up to index i inclusive
return -1;Return -1 if no pivot index found
function pivotIndex(nums) {
const n = nums.length;
const prefix = new Array(n + 1).fill(0);
for (let i = 0; i < n; i++) {
prefix[i + 1] = prefix[i] + nums[i];
}
for (let i = 0; i < n; i++) {
const leftSum = prefix[i];
const rightSum = prefix[n] - prefix[i + 1];
if (leftSum === rightSum) return i;
}
return -1;
}
// Test
console.log(pivotIndex([1,7,3,6,5,6])); // Output: 3
console.log(pivotIndex([2,1,-1])); // Output: 0
Line Notes
const prefix = new Array(n + 1).fill(0);Create prefix sums array initialized with zeros
prefix[i + 1] = prefix[i] + nums[i];Compute running totals for prefix sums
const leftSum = prefix[i];Left sum is prefix sum before index i
const rightSum = prefix[n] - prefix[i + 1];Right sum is total sum minus prefix sum up to index i inclusive
return -1;Return -1 if no pivot index found
Prefix sums are computed once in O(n), then each index is checked in O(1), total O(n).
💡 For n=100,000, this means about 200,000 operations, which is efficient for interviews.
Interview Verdict: Accepted
This approach is efficient and acceptable for large inputs, showing a clear improvement over brute force.