724. Find Pivot Index
Problem Description
The problem presents an array of integers and asks us to find what is known as the pivot index. The pivot index is when the sum of the numbers to the left of that index is equal to the sum of the numbers to the right of it. The problem clarifies a couple of edge cases:
- If the pivot index is at the very beginning of the array (index 0), the sum of the numbers to the left is considered to be 0 since there are no numbers left of it.
- Likewise, if the pivot is at the very end of the array, the sum of the numbers to the right is 0 for similar reasons.
Our task is to return the leftmost pivot index. In other words, we're looking for the first position from the left where this balance occurs. If no such index can be found where the sums to the left and right are equal, we must return -1
.
Intuition
The challenge is to find the pivot index without checking each possible index with brute force, which would be time-consuming for very large arrays. To make it more efficient, we can look for a way to find the balance as we go through the array just once.
To solve this problem, we need to track the sums of the numbers to the left and to the right of each index. An initial idea might be to calculate the sum of all numbers to the left and all those to the right for each index in the array. However, this would involve a lot of repeated work because we'd be summing over many of the same elements multiple times.
In the solution provided, we use a clever technique to avoid this repetition. We start by calculating the sum of the entire array and assign it to right
. As we iterate over each element with the index i
, we do the following:
-
Subtract the current element's value from
right
because we're essentially moving our 'pivot point' one step to the right, so everything that was once to the right is now either the pivot or to its left except the current element. -
Check if the current sums to the left and to the right of
i
(not includingi
) are equal. If they are,i
is our pivot index. -
If they're not equal, we add the current element's value to
left
because if we continue to the next element, our 'pivot point' will have moved, and the current element will now be considered part of the left sum.
By iterating over the array only once and updating left
and right
appropriately, we efficiently find the pivot index if it exists or determine that no pivot index is present.
Learn more about Prefix Sum patterns.
Solution Approach
The implementation of the solution involves a single pass over the array, which makes use of two helpful constructs:
-
Cumulative Sums: We don't calculate the sum on the fly for each pivot candidate; instead, we maintain a running total (
left
) that we build up as we iterate through the array. -
Total Sum: Before we start iterating, we calculate the total sum of the array (
right
). This sum represents everything that would initially be to the right of a hypothetical pivot at the start of the array.
Algorithmically, the steps are:
-
We initialize
left
to0
, since at the start of the array, there is nothing to the left. -
We initialize
right
to the sum of all elements innums
using thesum
function, representing the sum to the right of our starting index. -
We then iterate over each element
x
of the array alongside its indexi
using Python'senumerate
function, which gives us both the index and the value at that index in the array. -
For each element
x
, we deductx
fromright
, which now represents the sum of elements to the right of our current indexi
. -
We compare
left
andright
; if they are equal, we've found a pivot index, andi
is returned immediately. -
If
left
does not equalright
, we then add the value ofx
toleft
, preparing for the next iteration wherei
will be one index to the right. -
If we complete the entire loop without finding equal
left
andright
sums, which means there is no pivot index, we return-1
.
Thus, the approach cleverly manages the sum totals on either side of the current index by simply moving the index from left to right through the array, updating the sums by adding or subtracting the current element as appropriate. It does not require additional data structures or complex patterns but uses arithmetic operations judiciously to keep track of potential pivot indices.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's illustrate the solution approach with a small example. Consider the array nums = [1, 7, 3, 6, 5, 6]
.
-
Initial Setup: Start with
left
as0
andright
as the sum of the entire array, which is1 + 7 + 3 + 6 + 5 + 6 = 28
. -
First Iteration (i = 0):
-
We have
nums[i] = 1
, so updateright
to be the sum of numbers to the right of index 0.
right = right - nums[i] = 28 - 1 = 27
. -
Compare
left
andright
. Sinceleft
is0
andright
is27
, they are not equal, so index 0 is not a pivot. -
Update
left
to includenums[i]
.
left = left + nums[i] = 0 + 1 = 1
.
-
-
Second Iteration (i = 1):
-
nums[i] = 7
, so updateright
to be the sum of numbers to the right of index 1.
right = right - nums[i] = 27 - 7 = 20
. -
Compare
left
andright
.left
is1
andright
is20
, not equal, no pivot yet. -
Update
left
to includenums[i]
.
left = left + nums[i] = 1 + 7 = 8
.
-
-
Third Iteration (i = 2):
-
nums[i] = 3
, adjustright
.
right = right - nums[i] = 20 - 3 = 17
. -
Compare
left
andright
,left
is8
andright
is17
, not equal. -
Update
left
.
left = left + nums[i] = 8 + 3 = 11
.
-
-
Fourth Iteration (i = 3):
-
nums[i] = 6
, adjustright
.
right = right - nums[i] = 17 - 6 = 11
. -
Compare
left
andright
. Here both are11
, so we found a pivot indexi = 3
.
-
Since we've found a pivot index, we would return it (3
). If we hadn't found a pivot index at this point, we would've continued with the process for the rest of the array. If no pivot index was found after the last iteration, we'd return -1
.
This example walk-through demonstrates how the approach scans through the array, updating the sums of values to the left and right of the current index, and checks equality at each step without needing to sum over large subarrays repeatedly.
Solution Implementation
1from typing import List
2
3class Solution:
4 def pivotIndex(self, nums: List[int]) -> int:
5 # Initialize the left sum and right sum.
6 # Right sum is the sum of all elements initially.
7 left_sum, right_sum = 0, sum(nums)
8
9 # Iterate through the list
10 for index, element in enumerate(nums):
11 # Subtract the element from right sum as it will not be part of the right segment
12 right_sum -= element
13
14 # If left sum and right sum are equal, the current index is the pivot
15 if left_sum == right_sum:
16 return index # Return the pivot index
17
18 # Add the element to left sum as it becomes part of the left segment
19 left_sum += element
20
21 # If no pivot index is found, return -1.
22 return -1
23
1class Solution {
2 public int pivotIndex(int[] nums) {
3 // Initialize the sum of numbers to the left of the pivot to 0
4 int sumLeft = 0;
5
6 // Calculate the total sum of the array elements
7 int totalSum = 0;
8 for (int num : nums) {
9 totalSum += num;
10 }
11
12 // Iterate through the array to find the pivot index
13 for (int i = 0; i < nums.length; i++) {
14 // Right sum is total sum minus the current element
15 // since the current element is to be the pivot
16 int sumRight = totalSum - sumLeft - nums[i];
17
18 // If the sum of numbers to the left of the pivot is equal to
19 // the sum of numbers to the right of the pivot, return current index
20 if (sumLeft == sumRight) {
21 return i;
22 }
23
24 // Update the sumLeft by adding the current element's value
25 sumLeft += nums[i];
26 }
27
28 // If no pivot index is found, return -1
29 return -1;
30 }
31}
32
1#include <vector>
2#include <numeric> // Required for std::accumulate function
3
4class Solution {
5public:
6 // Function to find the pivot index of the array
7 int pivotIndex(vector<int>& nums) {
8 int sumLeft = 0; // Initialize sum of elements to the left of the pivot
9 // Compute the total sum of the array elements with std::accumulate
10 int sumRight = std::accumulate(nums.begin(), nums.end(), 0);
11
12 // Iterate over the array elements
13 for (int i = 0; i < nums.size(); ++i) {
14 sumRight -= nums[i]; // Subtract the current element from the right sum as it's under consideration
15
16 // If left sum is equal to right sum, the current index is the pivot index
17 if (sumLeft == sumRight) {
18 return i; // Return the current index as the pivot index
19 }
20
21 sumLeft += nums[i]; // Add the current element to the left sum before moving to the next element
22 }
23
24 return -1; // If no pivot index is found, return -1
25 }
26};
27
1// Function to find the pivot index of an array
2// The pivot index is where the sum of the numbers to the left of the index
3// is equal to the sum of the numbers to the right of the index
4function pivotIndex(nums: number[]): number {
5 let sumLeft = 0; // Initialize sum of elements to the left
6 let sumRight = nums.reduce((a, b) => a + b, 0); // Initialize sum of all elements
7
8 // Iterate through the array elements
9 for (let i = 0; i < nums.length; ++i) {
10 sumRight -= nums[i]; // Subtract the current element from the right sum
11
12 // Check if left sum and right sum are equal
13 if (sumLeft === sumRight) {
14 return i; // Return the current index as pivot index
15 }
16
17 sumLeft += nums[i]; // Add the current element to the left sum
18 }
19
20 return -1; // If no pivot index is found, return -1
21}
22
Time and Space Complexity
The time complexity of the given code is O(n)
, where n
is the number of elements in the nums
list. This is because we iterate over all elements of the array exactly once in a single loop to find the pivot index.
The space complexity of the code is O(1)
since we use only a constant amount of extra space for the variables left
, right
, i
, and x
irrespective of the input size.
Learn more about how to find time and space complexity quickly using problem constraints.
Consider the classic dynamic programming of longest increasing subsequence:
Find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order.
For example, the length of LIS for [50, 3, 10, 7, 40, 80]
is 4
and LIS is
[3, 7, 40, 80]
.
What is the recurrence relation?
Recommended Readings
Prefix Sum The prefix sum is an incredibly powerful and straightforward technique Its primary goal is to allow for constant time range sum queries on an array What is Prefix Sum The prefix sum of an array at index i is the sum of all numbers from index 0 to i By
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Want a Structured Path to Master System Design Too? Don’t Miss This!