↓Skip to main content
  1. LeetCode/

LeetCode 3638: Maximum Balanced Shipments

·2 mins· ·
LeetCode Medium Dynamic-Programming Greedy Monotonic-Stack Array
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2025-08-03

  • Submissions: Wrong Answer → Accepted

Approach
#

A segment is valid ⇔ its last value is strictly less than its maximum.

Greedy: cut as soon as possible. Going left to right, as soon as the current value is below the segment’s maximum, end the segment and start a new one. Ending early never reduces later cuts (no later element is used up).

Before a cut, the segment is always non-decreasing (otherwise it would have been cut already), so its maximum is the previous value. Comparing weight[i] < weight[i - 1] is enough.

My Attempts
#

Attempt 1 remembered the segment’s first value and kept comparing against it instead of the maximum. For weight = [1, 5, 2], the maximum of [1, 5, 2] is 5 and 2 < 5, so it forms one segment and the answer is 1; but 2 is not below the first value 1, so this returned 0.

Updating the remembered value to the current value (the maximum) whenever no cut happens passed.

Solution
#

class Solution:
    def maxBalancedShipments(self, weight: List[int]) -> int:
        count = 0
        prev = None                                # the segment's max so far (= previous value)
        for w in weight:
            if prev is not None and w < prev:
                count += 1                         # cut as soon as possible
                prev = None                        # start a new segment
            else:
                prev = w
        return count

Complexity
#

Time O(n), space O(1).

Mistakes to Avoid
#

  • Comparing with the segment’s first value: compare with its maximum.
  • After a cut, start over; the next value begins a new segment.

Interview Explanation
#

A segment is valid when its last value is below its maximum. Greedily I cut as soon as possible, since ending early wastes no later elements. Before a cut the segment is non-decreasing, so its maximum is the previous value, and comparing neighbors is enough. Time O(n).

Related

LeetCode 435: Non-overlapping Intervals
·2 mins
LeetCode Medium Array Dynamic-Programming Greedy Sorting
LeetCode 435 note: minimum removals = total minus the maximum kept; sort by right end and greedily keep the one ending earliest
LeetCode 3627: Maximum Median Sum of Subsequences of Size 3
·2 mins
LeetCode Medium Math Greedy Sorting Game-Theory Array
LeetCode 3627 note: after sorting, each group takes the two largest and the smallest, with the second largest as the median; the answer takes every other value from the end, n / 3 of them
LeetCode 3075: Maximize Happiness of Selected Children
·1 min
LeetCode Medium Array Greedy Sorting
LeetCode 3075 note: choose k children from the happiest, where the i-th choice loses i, floored at 0
LeetCode 611: Valid Triangle Number
·2 mins
LeetCode Medium Array Two-Pointers Binary-Search Greedy
LeetCode 611 note: sort, fix the longest side k, and use two pointers for the shorter sides; when the sum is large enough every i in between works, adding j - i at once
LeetCode 324: Wiggle Sort II
·2 mins
LeetCode Medium Array Divide-and-Conquer Greedy Sorting
LeetCode 324 note: sort, split into a small half and a large half, reverse each, and interleave with small values at even indices and large ones at odd indices
LeetCode 334: Increasing Triplet Subsequence
·2 mins
LeetCode Medium Array Greedy Longest-Increasing-Subsequence
LeetCode 334 note: keep the smallest first and the smallest second that has something smaller before it; any number above second completes a triplet