3721. Longest Balanced Subarray II
Difficulty: Hard
Topics: Principal, Array, Hash Table, Divide and Conquer, Segment Tree, Prefix Sum, Weekly Contest 472
You are given an integer array nums.
A subarray1 is called balanced if the number of distinct even numbers in the subarray is equal to the number of distinct odd numbers.
Return the length of the longest balanced subarray.
Example 1:
- Input: nums = [2,5,4,3]
- Output: 4
-
Explanation:
- The longest balanced subarray is
[2, 5, 4, 3]. - It has 2 distinct even numbers
[2, 4]and 2 distinct odd numbers[5, 3]. Thus, the answer is 4.
- The longest balanced subarray is
Example 2:
- Input: nums = [3,2,2,5,4]
- Output: 5
-
Explanation:
- The longest balanced subarray is
[3, 2, 2, 5, 4]. - It has 2 distinct even numbers
[2, 4]and 2 distinct odd numbers[3, 5]. Thus, the answer is 5.
- The longest balanced subarray is
Example 3:
- Input: nums = [1,2,3,2]
- Output: 3
-
Explanation:
- The longest balanced subarray is
[2, 3, 2]. - It has 1 distinct even number
[2]and 1 distinct odd number[3]. Thus, the answer is 3.
- The longest balanced subarray is
Constraints:
1 <= nums.length <= 10⁵1 <= nums[i] <= 10⁵
Hint:
- Store the first (or all) occurrences for each value in
pos[val]. - Build a lazy segment tree over start indices
l in [0..n-1]that supports range add and can tell if any index has value0(keepmn/mx). - Use
sign = +1for odd values andsign = -1for even values. - Initialize by adding each value's contribution with
update(p, n-1, sign)wherepis its current first occurrence. - Slide left
l: poppos[nums[l]], letnext= next occurrence orn, doupdate(0, next-1, -sign), then query for anyr >= lwith value0and updateans = max(ans, r-l+1).
Solution:
We need to analyze the provided solution and create an approach and explanation in bullet points. The problem: Longest Balanced Subarray II. The definition: a subarray is balanced if the number of distinct even numbers equals the number of distinct odd numbers. The solution uses prefix sums with a segment tree, tracking a balance value based on contributions of distinct numbers as we slide the left boundary. It's a fairly complex solution.
Approach:
- Represent each distinct number by a sign:
+1for odd,-1for even. A subarray is balanced if the sum of signs of its distinct numbers equals0. - For a fixed left boundary
l, define a balance arrayB_l[r]as the sum of signs of all distinct numbers whose first occurrence inside[l, r]is at or beforer. Finding the longest balanced subarray becomes: for eachl, find the largestr ≥ lwithB_l[r] = 0. - Precompute
next_occ[i]– the next occurrence of the same value, ornif none. Precomputefirst_occ[val]– the first occurrence of each value. - Build the initial balance
B_0using prefix sums on the first occurrences. Each distinct value contributes its sign at its first occurrence, and then for all later indices via prefix sum. - Maintain a segment tree over
B_0that supports:- range add – to update the balance when the left boundary moves,
- query rightmost index with value 0 in a given range.
- Sweep the left boundary
lfrom0ton-1:- Query the segment tree for the rightmost
r ≥ lwhere the current balance is0. Update the answer. - If this is not the last element, remove the contribution of
nums[l]:- Get its sign and its next occurrence
next. - The element
nums[l]was the first occurrence for[l, …]. After moving tol+1, its contribution vanishes for allr < next. - Perform a range add of
-signon the interval[0, next-1]of the segment tree.
- Get its sign and its next occurrence
- Query the segment tree for the rightmost
- After the sweep, the maximum length found is the answer.
Let's implement this solution in PHP: 3721. Longest Balanced Subarray II
<?php
/**
* @param Integer[] $nums
* @return Integer
*/
function longestBalanced(array $nums): int
{
...
...
...
/**
* go to ./solution.php
*/
}
// Test cases
echo longestBalanced([2,5,4,3]) . "\n"; // Output: 4
echo longestBalanced([3,2,2,5,4]) . "\n"; // Output: 5
echo longestBalanced([1,2,3,2]) . "\n"; // Output: 3
?>
Explanation:
Why signs work
Each distinct even number adds-1, each distinct odd adds+1.
A balanced subarray requires equal counts → sum = 0.From subarray condition to balance array
For a fixed leftl, the distinct numbers in[l,r]are exactly those values whose first occurrence in that subarray is≤ r.
If we place the sign of a value at its first occurrence relative to l and propagate it to the right, the prefix sum atrbecomesB_l[r]– the net balance.Initialising for
l=0
For every value we store its global first occurrence. We add its sign at that position, then compute the prefix sum. This givesB_0[r]for allr.-
Segment tree capabilities
We need to repeatedly:- Add a constant to a contiguous range of
Bvalues (when left moves). - Quickly find the rightmost index
≥ lwith value0. A lazy segment tree storingmin,max, and the position of the rightmost zero (if any) per node handles both inO(log n)per operation.
- Add a constant to a contiguous range of
Sliding the left boundary
When we move fromltol+1, the element atldisappears.
Letv = nums[l], signs, and its next occurrencenext.
Before removal,vcontributedsto everyr ≥ l(because its first occurrence in[l,r]wasl).
After removal,vcontributessonly tor ≥ next.
Therefore, for allrwithl ≤ r < next, the contribution is removed.
Updating the whole range[0, next-1]by-sis safe because we never query indices< l, and it correctly removes the contribution forr ≥ lwhile leaving values forr ≥ nextunchanged.Querying
For eachl, we ask the segment tree: “Give me the largestrin[l, n-1]with balance0”.
If such anrexists, the subarray[l,r]is balanced and its length isr-l+1.Complexity
Preprocessing:O(n).
Segment tree operations: eachrange_addandquery_rightmost_zeroruns inO(log n).
We perform exactlynqueries and at mostnupdates – totalO(n log n).
This meets the constraintn ≤ 10⁵.Why not a simpler two‑pointer?
The “distinct” condition breaks the monotonicity of usual sliding window.
The first‑occurrence / next‑occurrence trick together with a segment tree elegantly decouples the distinctness handling from the window movement.
Contact Links
If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

If you want more helpful content like this, feel free to follow me:
-
Subarray: A subarray is a contiguous non-empty sequence of elements within an array. ↩
Top comments (0)