Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions problems/2574-left-and-right-sum-differences/analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# 2574. Left and Right Sum Differences

[LeetCode Link](https://leetcode.com/problems/left-and-right-sum-differences/)

Difficulty: Easy
Topics: Array, Prefix Sum
Acceptance Rate: 88.5%

## Hints

### Hint 1

For each index `i` you need to know the sum of everything *before* it and the sum of everything *after* it. Before reaching for nested loops, ask yourself: is there a way to reuse work you've already done as you scan across the array? This is the classic territory of the **prefix sum** pattern.

### Hint 2

Notice a useful relationship: if you know the **total sum** of the array and you keep a running **left sum** as you move from left to right, then the right sum at index `i` falls out for free. There's no need to compute `rightSum` with a separate pass over the elements to the right.

### Hint 3

At index `i`, let `left` be the sum of `nums[0..i-1]`. Then `rightSum[i] = total - left - nums[i]`, where `total` is the sum of the whole array. So `answer[i] = |left - (total - left - nums[i])|`. Compute `total` once, then sweep through once while updating `left` after you record each answer.

## Approach

The brute-force idea is to, for every index `i`, loop over all elements left of `i` and all elements right of `i`. That is `O(n^2)` and wasteful because it recomputes overlapping sums again and again.

We can do much better by recognizing that the left sums form a running total. Walk the array once and maintain a single accumulator `left` that holds the sum of all elements strictly to the left of the current index.

The right sum never needs its own loop. If `total` is the sum of every element, then the sum strictly to the right of index `i` is simply everything except the left part and the current element:

```
rightSum[i] = total - left - nums[i]
```

Algorithm:

1. Compute `total`, the sum of all elements in `nums`.
2. Initialize `left = 0` and an `answer` slice of length `n`.
3. For each index `i` from `0` to `n-1`:
- Compute `right = total - left - nums[i]`.
- Set `answer[i] = abs(left - right)`.
- Add `nums[i]` to `left` so it is ready for the next index.
4. Return `answer`.

Walking through Example 1, `nums = [10, 4, 8, 3]`, `total = 25`:

| i | nums[i] | left (before) | right = 25 - left - nums[i] | answer = \|left - right\| |
|---|---------|---------------|-----------------------------|---------------------------|
| 0 | 10 | 0 | 25 - 0 - 10 = 15 | \|0 - 15\| = 15 |
| 1 | 4 | 10 | 25 - 10 - 4 = 11 | \|10 - 11\| = 1 |
| 2 | 8 | 14 | 25 - 14 - 8 = 3 | \|14 - 3\| = 11 |
| 3 | 3 | 22 | 25 - 22 - 3 = 0 | \|22 - 0\| = 22 |

This yields `[15, 1, 11, 22]`, matching the expected output.

This works because `left` is exactly `leftSum[i]` by construction (we only add `nums[i]` *after* recording the answer), and the right sum is derived from the invariant `total = leftSum[i] + nums[i] + rightSum[i]`.

## Complexity Analysis

Time Complexity: O(n) — one pass to compute the total and one pass to fill the answer.
Space Complexity: O(1) extra — ignoring the output array, we only keep a couple of integer accumulators. (The returned `answer` array is O(n), which is unavoidable.)

## Edge Cases

- **Single element** (`nums = [1]`): There is nothing to the left or right, so `leftSum[0] = rightSum[0] = 0` and the answer is `[0]`. The formula handles this automatically: `right = total - 0 - nums[0] = 0`.
- **All elements equal**: The running-sum logic still holds; this just confirms there are no off-by-one mistakes in updating `left`.
- **Largest array (n = 1000) with max values**: The total can be up to `1000 * 10^5 = 10^8`, which fits comfortably in Go's `int` (64-bit on common platforms, at least 32-bit guaranteed), so there is no overflow concern.
- **Absolute value**: Remember the answer uses `|leftSum - rightSum|`; forgetting the absolute value would produce negative numbers for early indices where the right side dominates.
56 changes: 56 additions & 0 deletions problems/2574-left-and-right-sum-differences/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
number: "2574"
frontend_id: "2574"
title: "Left and Right Sum Differences"
slug: "left-and-right-sum-differences"
difficulty: "Easy"
topics:
- "Array"
- "Prefix Sum"
acceptance_rate: 8849.8
is_premium: false
created_at: "2026-06-06T04:34:39.054903+00:00"
fetched_at: "2026-06-06T04:34:39.054903+00:00"
link: "https://leetcode.com/problems/left-and-right-sum-differences/"
date: "2026-06-06"
---

# 2574. Left and Right Sum Differences

You are given a **0-indexed** integer array `nums` of size `n`.

Define two arrays `leftSum` and `rightSum` where:

* `leftSum[i]` is the sum of elements to the left of the index `i` in the array `nums`. If there is no such element, `leftSum[i] = 0`.
* `rightSum[i]` is the sum of elements to the right of the index `i` in the array `nums`. If there is no such element, `rightSum[i] = 0`.



Return an integer array `answer` of size `n` where `answer[i] = |leftSum[i] - rightSum[i]|`.



**Example 1:**


**Input:** nums = [10,4,8,3]
**Output:** [15,1,11,22]
**Explanation:** The array leftSum is [0,10,14,22] and the array rightSum is [15,11,3,0].
The array answer is [|0 - 15|,|10 - 11|,|14 - 3|,|22 - 0|] = [15,1,11,22].


**Example 2:**


**Input:** nums = [1]
**Output:** [0]
**Explanation:** The array leftSum is [0] and the array rightSum is [0].
The array answer is [|0 - 0|] = [0].




**Constraints:**

* `1 <= nums.length <= 1000`
* `1 <= nums[i] <= 105`
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package main

// 2574. Left and Right Sum Differences
//
// Approach: prefix sum in a single pass. Compute the total sum once, then sweep
// left to right maintaining a running `left` sum. The right sum at index i is
// derived for free as total - left - nums[i], since
// total = leftSum[i] + nums[i] + rightSum[i]. The answer is the absolute
// difference between the left and right sums.
//
// Time: O(n), Space: O(1) extra (excluding the output array).
func leftRightDifference(nums []int) []int {
total := 0
for _, v := range nums {
total += v
}

answer := make([]int, len(nums))
left := 0
for i, v := range nums {
right := total - left - v
answer[i] = abs(left - right)
left += v
}
return answer
}

func abs(x int) int {
if x < 0 {
return -x
}
return x
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import (
"reflect"
"testing"
)

func TestSolution(t *testing.T) {
tests := []struct {
name string
nums []int
expected []int
}{
{
name: "example 1: [10,4,8,3]",
nums: []int{10, 4, 8, 3},
expected: []int{15, 1, 11, 22},
},
{
name: "example 2: single element",
nums: []int{1},
expected: []int{0},
},
{
name: "edge case: two elements",
nums: []int{5, 9},
expected: []int{9, 5},
},
{
name: "edge case: all equal elements",
nums: []int{3, 3, 3},
expected: []int{6, 0, 6},
},
{
name: "edge case: symmetric array",
nums: []int{1, 2, 1},
expected: []int{3, 0, 3},
},
{
name: "edge case: max single value",
nums: []int{100000},
expected: []int{0},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := leftRightDifference(tt.nums)
if !reflect.DeepEqual(result, tt.expected) {
t.Errorf("leftRightDifference(%v) = %v, want %v", tt.nums, result, tt.expected)
}
})
}
}