Given a 0-indexed integer array nums, find the leftmost middleIndex (i.e., the smallest amongst all the possible ones).
A middleIndex is an index where nums[0] + nums[1] + ... + nums[middleIndex-1] == nums[middleIndex+1] + nums[middleIndex+2] + ... + nums[nums.length-1].
If middleIndex == 0, the left side sum is considered to be 0. Similarly, if middleIndex == nums.length - 1, the right side sum is considered to be 0.
Return the leftmost middleIndex that satisfies the condition, or -1 if there is no such index.
Example 1:
Input: nums = [2,3,-1,8,4] Output: 3 Explanation: The sum of the numbers before index 3 is: 2 + 3 + -1 = 4 The sum of the numbers after index 3 is: 4 = 4
Example 2:
Input: nums = [1,-1,4] Output: 2 Explanation: The sum of the numbers before index 2 is: 1 + -1 = 0 The sum of the numbers after index 2 is: 0
Example 3:
Input: nums = [2,5] Output: -1 Explanation: There is no valid middleIndex.
Constraints:
1 <= nums.length <= 100-1000 <= nums[i] <= 1000Note: This question is the same as 724: https://leetcode.com/problems/find-pivot-index/
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We're figuring out where the middle is by exhaustively checking. We'll consider every single spot in the list as a possible middle, one at a time. For each spot, we'll compare the 'weight' on the left to the 'weight' on the right.
Here's how the algorithm would work step-by-step:
def find_middle_index_brute_force(numbers):
for potential_middle_index in range(len(numbers)):
left_sum = 0
for index_on_left in range(potential_middle_index):
left_sum += numbers[index_on_left]
# Reset the right sum for each middle index
right_sum = 0
for index_on_right in range(potential_middle_index + 1, len(numbers)):
right_sum += numbers[index_on_right]
# Check sums, we found the middle
if left_sum == right_sum:
return potential_middle_index
# No middle found, weights never match
return -1The key is to avoid redundant calculations. Instead of repeatedly summing sections of the collection, we calculate a cumulative sum from one side and use that to efficiently derive sums from the opposite side when needed.
Here's how the algorithm would work step-by-step:
def find_middle_index(numbers):
total_sum = sum(numbers)
running_sum = 0
for i, number in enumerate(numbers):
# Check if left sum equals right sum
if running_sum == (total_sum - running_sum - number):
return i
# Keep a running sum of the left side
running_sum += number
# If no middle index is found
return -1| Case | How to Handle |
|---|---|
| Null or empty array input | Return -1 immediately, as a middle index cannot exist in an empty array. |
| Array with only one element | Return 0 as the first and only element satisfies the condition of having equal sum on both sides. |
| Array with all elements equal to zero | Return 0 as the first index since the sum on both sides will always be 0. |
| Array with a large number of elements (performance considerations) | Use a prefix sum approach for O(n) time complexity to efficiently handle large arrays. |
| Integer overflow when calculating sums, especially with large positive or negative numbers | Use long data type to store sums to prevent potential integer overflows. |
| Array where no middle index exists | Return -1 after iterating through the entire array and not finding a suitable middle index. |
| Array with negative numbers | The algorithm should handle negative numbers correctly since it's based on calculating sums. |
| Array with extreme boundary values (Integer.MAX_VALUE, Integer.MIN_VALUE) | Using long avoids overflow which would be relevant in boundary value calculations. |