Advertisement

Partition Array Into Three Parts With Equal Sum - LeetCode 1013 Solution

Partition Array Into Three Parts With Equal Sum - Complete Solution Guide

Partition Array Into Three Parts With Equal Sum is LeetCode problem 1013, a Easy level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

Given an array of integers arr , return true if we can partition the array into three non-empty parts with equal sums. Formally, we can partition the array if we can find indexes i + 1 < j with (arr[0] + arr[1] + ... + arr[i] == arr[i + 1] + arr[i + 2] + ... + arr[j - 1] == arr[j] + arr[j + 1] + ... + arr[arr.length - 1]) Example 1: Input: arr = [0,2,1,-6,6,-7,9,1,2,0,1] Output: true Explanation: 0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1 Example 2: Input: arr = [0,2,1,-6,6,7,9,-1,2,0,1] Output:

Detailed Explanation

Imagine you have a long sequence of numbers, and your task is to chop it into exactly three distinct, contiguous sections. The catch? Each of these three sections must add up to the *exact same sum*. This is precisely what problem #1013 asks us to determine. We're given an array `arr` and need to return `true` if we can find two split points, `i` and `j`, such that the sum of `arr[0...i]`, `arr[i+1...j-1]`, and `arr[j...arr.length-1]` are all equal. Crucially, the problem specifies `i + 1 < j`, which means the middle section (`arr[i+1...j-1]`) cannot be empty; it must contain at least one element, ensuring proper separation between the first and third parts.

Solution Approach

The provided solution takes a remarkably straightforward and efficient greedy approach. First, it calculates the `total_sum` of all elements in the array. This is our foundation. If `total_sum` isn't perfectly divisible by 3, there's no way to achieve three equal parts, so we immediately return `false`. Otherwise, we calculate our `target_sum`, which is simply `total_sum // 3`. Now, the core of the algorithm iterates through the array, accumulating `current_sum` as it goes. The key insight is that we're essentially trying to "find" each of the three parts sequentially. As soon as `current_sum` equals our `target_sum`, we've successfully identified the end of one segment. We increment a `count` variable, signifying we've found one such part, and then reset `current_sum` back to 0. This reset is crucial: it effectively tells us to start accumulating for the *next* potential part from that point onwards. We continue this process until we've iterated through the entire array. Finally, we return `true` if `count >= 3`. Why `count >= 3` and not `count == 3`? Because if `target_sum` is 0 (e.g., `[0,0,0,0,0,0]`), you might find more than three segments that sum to 0. The crucial point is that if we successfully find *two* segments that each sum to `target_sum`, then by definition, the *remainder* of the array (from where the second segment ended to the very end) *must* also sum to `target_sum`. This is because `total_sum = target_sum + target_sum + (remaining_sum)`. Since `total_sum = 3 * target_sum`, it follows that `remaining_sum` must also be `target_sum`. So, by the time our loop has found `count` equal to 2, and then the sum reaches `target_sum` *again* (making `count` 3), it implicitly confirms that the remaining portion of the array also sums up correctly. The `count >= 3` then correctly handles cases like `[0,0,0,0,0,0]` where each `0` could technically be a part, and we just need *at least three* to form the required structure, while implicitly respecting the non-empty part constraint as each '0' is itself a valid non-empty part.

Step-by-Step Algorithm

  1. Step 1: Calculate the total sum of the array.
  2. Step 2: Check if the total sum is divisible by 3. If not, return `false`.
  3. Step 3: Calculate the target sum (total sum / 3).
  4. Step 4: Initialize a `currentSum` to 0 and a `count` to 0.
  5. Step 5: Iterate through the array. Add each element to `currentSum`.
  6. Step 6: If `currentSum` equals the `targetSum`, increment `count` and reset `currentSum` to 0.
  7. Step 7: After iterating, check if `count` is greater than or equal to 3. If so, return `true`; otherwise, return `false`.

Key Insights

  • **Divisibility Check First:** The most fundamental prerequisite is that the entire array's sum *must* be perfectly divisible by 3. If `sum(arr) % 3 != 0`, it's mathematically impossible to partition it into three equal sum parts, so we can immediately short-circuit and return `false`. This initial check prunes a large portion of invalid inputs efficiently.
  • **Greedy Sequential Accumulation with Reset:** The core strategy involves a single pass through the array, greedily accumulating `current_sum`. When `current_sum` hits the `target_sum` (which is `total_sum / 3`), we effectively "cut" that segment, increment our `count` of found parts, and crucially, *reset `current_sum` to 0*. This reset prepares us to find the *next* independent part from the point where the previous one ended.
  • **Implicit Third Part Verification and `count >= 3`:** The algorithm doesn't explicitly search for the third part as a distinct operation. Instead, once two segments are found, the fact that `total_sum = 3 * target_sum` guarantees that the *remaining* part of the array must also sum to `target_sum`. The `count >= 3` condition is robust because it confirms we've found at least two valid split points, implicitly creating three valid sections. It also correctly handles scenarios where `target_sum` is zero, allowing for more than three segments to sum to zero, while still validating the minimal requirement.

Complexity Analysis

Time Complexity: O(n)

Space Complexity: O(1)

Topics

This problem involves: Array, Greedy.

Companies

Asked at: Turing.