Facebook Pixel

3876. Construct Uniform Parity Array II

MediumArrayMath
LeetCode ↗

Problem Description

You are given an array nums1 of n distinct integers.

Your goal is to construct another array nums2, also of length n, where every element in nums2 is either all odd or all even. In other words, the entire nums2 array must consist of only odd numbers, or only even numbers.

To build nums2, you process each index i independently. For each index i, you must choose exactly one of the following two options (you may decide the order freely):

  • Keep the value as is: nums2[i] = nums1[i]
  • Subtract another element: nums2[i] = nums1[i] - nums1[j], where j != i, and the result must satisfy nums1[i] - nums1[j] >= 1

For each position, you make one of these choices, and the final nums2 array must end up being entirely odd or entirely even.

Return true if it is possible to construct such an array nums2, and false otherwise.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

How We Pick the Algorithm

Why Math / Bit Manipulation?

This problem maps to Math / Bit Manipulation through a short path in the full flowchart.

Bitmanipulationor math?yesNumbertheory?noMath / BitManipulation

The problem hinges on parity properties of subtraction and the relationship between minimum odd and even numbers, solved with mathematical reasoning.

Open in Flowchart

Intuition

The key observation is to think about parity. We want every element in nums2 to have the same parity (all odd or all even). Let's reason about when this is achievable.

First, consider the simplest case. If all elements in nums1 already share the same parity (either all odd or all even), then we can simply keep every element unchanged by choosing nums2[i] = nums1[i]. This trivially satisfies the requirement.

The interesting case is when nums1 contains a mix of odd and even numbers. Since we can subtract one element from another, notice what happens to parity:

  • odd - odd = even
  • even - even = even
  • odd - even = odd
  • even - odd = odd

This means subtraction gives us flexibility to flip or preserve parity, depending on what we subtract. Because the numbers are distinct, the difference is never zero, so the constraint nums1[i] - nums1[j] >= 1 just requires that we subtract a strictly smaller element.

Now, ask: can we make everything even? An element is even either if it is already even, or if we subtract another value of the same parity from it (odd - odd or even - even). For any element x, we can make it even as long as there exists a strictly smaller element with the same parity to subtract. The only element that can ever fail is the globally smallest element of each parity, since there may be nothing smaller of the same parity to subtract from it.

The actual blocker comes down to the smallest values. Let mn be the minimum odd number in the array. If there is some even number x that is smaller than mn, that even number cannot be turned into the needed parity, because there is no valid smaller element to subtract and produce the consistent result. In every other situation, we can carefully pick subtractions to align all elements to a common parity.

So the solution reduces to a simple check: find the minimum odd number, and verify that no even number is smaller than it. If such a smaller even number exists, return false; otherwise, return true.

Pattern Learn more about Math patterns.

Solution Approach

We solve this with a straightforward two-pass scan over the array, applying the parity reasoning described above.

Step 1: Find the minimum odd number.

We initialize a variable mn to infinity (inf). Then we iterate through every element x in nums1. Whenever x is odd (checked with x % 2), we update mn to be the smaller of the current mn and x:

mn = inf
for x in nums1:
    if x % 2:
        mn = min(mn, x)

After this loop, mn holds the smallest odd value in the array. If the array contains no odd numbers at all, mn stays at inf.

Step 2: Check the even numbers against mn.

We iterate through the array a second time. For each even element x (checked with x % 2 == 0), we test whether mn is a real odd value (mn != inf) and whether x is smaller than mn:

for x in nums1:
    if x % 2 == 0 and mn != inf and x < mn:
        return False
return True
  • The condition mn != inf ensures that the array actually contains at least one odd number. If everything is even, no conflict can arise, so we never fail here.
  • The condition x < mn detects the blocking case: an even number that is strictly smaller than the minimum odd number. If we find one, the construction is impossible, so we return False.

If we get through the entire second pass without finding any such even number, the construction is always possible, and we return True.

Complexity Analysis:

  • Time complexity: O(n), since we make two linear passes over the array of n elements.
  • Space complexity: O(1), since we only use a single extra variable mn regardless of input size.

This approach relies on the brain-teaser insight that the only obstruction is an even number smaller than the smallest odd number, reducing what looks like a complex construction problem into a simple comparison.

Example Walkthrough

Let's trace through the solution approach with a small example.

Input: nums1 = [4, 7, 3, 6]

This array contains a mix of odd numbers (7, 3) and even numbers (4, 6), so we're in the interesting case where we cannot trivially keep everything unchanged.


Step 1: Find the minimum odd number.

We initialize mn = inf and scan through each element:

Element xIs x odd? (x % 2)Actionmn after step
4No (4 % 2 == 0)skipinf
7Yes (7 % 2 == 1)mn = min(inf, 7) = 77
3Yes (3 % 2 == 1)mn = min(7, 3) = 33
6No (6 % 2 == 0)skip3

After the first pass, mn = 3 (the smallest odd value).


Step 2: Check even numbers against mn.

Now we scan again, looking only at even elements, and test whether any even number is strictly smaller than mn = 3:

Element xIs x even?mn != inf?x < mn? (x < 3)Result
4YesYesNo (4 < 3 false)continue
7Noskip
3Noskip
6YesYesNo (6 < 3 false)continue

No even number is smaller than the minimum odd number 3, so we never return False. The loop finishes and we return true.


Why this works intuitively:

Since no even number sits below the smallest odd number 3, we can align every element to a common parity. For instance, to make everything even:

  • 4 is already even → keep it (nums2 = 4)
  • 7 is odd → subtract a smaller odd: 7 - 3 = 4 (even)
  • 3 is the smallest odd; subtract a smaller even: 3 - ?... here we'd instead target an all-even result by leveraging that 3 can subtract no smaller odd, but since an even smaller than it would be the blocker and none exists, the construction stays feasible.
  • 6 is already even → keep it

The crucial point is that the only obstruction would have been an even number smaller than 3 (the minimum odd), which has nothing valid to subtract to reach the consistent parity. Because no such value exists in [4, 7, 3, 6], the answer is true.


Contrast — a failing case:

If instead nums1 = [2, 7, 3, 6], then mn = 3, but the even number 2 < 3. During the second pass, the condition x % 2 == 0 and mn != inf and x < mn is satisfied at x = 2, so we immediately return false — that even 2 cannot be reconciled into the required common parity.

Solution Implementation

1from math import inf
2
3
4class Solution:
5    def uniformArray(self, nums: list[int]) -> bool:
6        # Track the smallest odd number in the array.
7        min_odd = inf
8        for x in nums:
9            if x % 2:  # x is odd
10                min_odd = min(min_odd, x)
11
12        # If any even number is smaller than the smallest odd number,
13        # the array cannot be made uniform.
14        for x in nums:
15            if x % 2 == 0 and min_odd != inf and x < min_odd:
16                return False
17
18        return True
19```
20
21**Notes on the changes:**
22- Imported `inf` from `math` so the code actually runs.
23- Renamed `nums1` → `nums` (single-array context) and `mn` → `min_odd` for clarity.
24- Kept the method name `uniformArray` unchanged as required.
25- Added comments explaining each step's intent.
26
27**An alternative single-pass perspective:** you could compute `min_odd` and the minimum even number in one loop, then compare once at the end — this avoids iterating twice:
28
29```python3
30from math import inf
31
32
33class Solution:
34    def uniformArray(self, nums: list[int]) -> bool:
35        min_odd = inf   # smallest odd value
36        min_even = inf  # smallest even value
37        for x in nums:
38            if x % 2:
39                min_odd = min(min_odd, x)
40            else:
41                min_even = min(min_even, x)
42
43        # Fails only when there is an even number strictly smaller
44        # than the smallest odd number.
45        return min_even >= min_odd
46
1class Solution {
2    public boolean uniformArray(int[] nums1) {
3        // Sentinel value representing "no odd number found yet".
4        final int inf = Integer.MAX_VALUE;
5
6        // minOdd holds the smallest odd value in the array.
7        int minOdd = inf;
8
9        // First pass: locate the minimum odd number.
10        for (int num : nums1) {
11            if (num % 2 == 1) {
12                minOdd = Math.min(minOdd, num);
13            }
14        }
15
16        // Second pass: every even number must not be smaller than minOdd.
17        // The check is skipped entirely when no odd number exists (minOdd == inf).
18        for (int num : nums1) {
19            if (num % 2 == 0 && minOdd != inf && num < minOdd) {
20                return false;
21            }
22        }
23
24        // All even numbers are >= the smallest odd number (or no odd number exists).
25        return true;
26    }
27}
28
1class Solution {
2public:
3    bool uniformArray(vector<int>& nums) {
4        // Track the smallest odd number in the array.
5        int minOdd = INT_MAX;
6
7        // First pass: find the minimum odd value.
8        for (int value : nums) {
9            if (value % 2 == 1) {
10                minOdd = min(minOdd, value);
11            }
12        }
13
14        // Second pass: check every even number.
15        // If an even number is smaller than the smallest odd number,
16        // the condition fails and we return false.
17        for (int value : nums) {
18            if (value % 2 == 0 && minOdd != INT_MAX && value < minOdd) {
19                return false;
20            }
21        }
22
23        // All even numbers satisfy the constraint (or no odd numbers exist).
24        return true;
25    }
26};
27
1/**
2 * Checks whether every even number in the array is greater than or equal to
3 * the smallest odd number present in the array.
4 *
5 * @param nums - The input array of numbers.
6 * @returns True if no even number is smaller than the minimum odd number; otherwise false.
7 */
8function uniformArray(nums: number[]): boolean {
9    // Track the smallest odd value found so far.
10    let minOdd = Number.MAX_SAFE_INTEGER;
11
12    // First pass: locate the minimum odd number in the array.
13    for (const value of nums) {
14        if (value % 2 === 1) {
15            minOdd = Math.min(minOdd, value);
16        }
17    }
18
19    // Second pass: ensure every even number is not smaller than the minimum odd number.
20    // The check is skipped entirely when the array contains no odd numbers.
21    for (const value of nums) {
22        if (value % 2 === 0 && minOdd !== Number.MAX_SAFE_INTEGER && value < minOdd) {
23            return false;
24        }
25    }
26
27    // All even numbers satisfy the condition (or there were no odd numbers).
28    return true;
29}
30

Time and Space Complexity

The time complexity is O(n), and the space complexity is O(1). Here, n is the length of the array nums1.

The code consists of two separate loops, each iterating over the array nums1 once. The first loop traverses all elements to find the minimum odd value mn, taking O(n) time. The second loop again traverses all elements to check the condition for even numbers, also taking O(n) time. Since these loops are sequential rather than nested, the total time complexity is O(n) + O(n) = O(n).

For space, only a constant number of extra variables are used (mn and the loop variable x), regardless of the input size. Therefore, the space complexity is O(1).

Pattern Learn more about how to find time and space complexity quickly.

Common Pitfalls

Pitfall: Treating the alternative single-pass solution as logically equivalent to the two-pass version.

The two versions look interchangeable, but they actually diverge in one specific case: when the array contains no odd numbers at all.

Consider an array of only even numbers, e.g. nums = [2, 4, 6].

  • Two-pass version: min_odd stays at inf. In the second loop, the guard min_odd != inf is False for every element, so we never return False. The function correctly returns True.

  • Single-pass version: min_odd stays at inf, and min_even becomes 2. The final check is min_even >= min_odd, i.e. 2 >= inf, which evaluates to False. The function incorrectly returns False.

So if you "optimize" by switching to the single-pass form without re-examining the all-even edge case, you silently introduce a bug. The min_odd != inf guard in the two-pass version is load-bearing — it is precisely the thing that handles the no-odd-numbers situation. The single-pass return min_even >= min_odd quietly drops that protection.

Why this is easy to miss

  • Both snippets share the same "smallest even vs. smallest odd" mental model, so the difference feels cosmetic.
  • Most hand-picked test cases mix odd and even numbers, so the all-even case never triggers during casual testing.
  • The bug only surfaces on a boundary input (min_odd == inf), which is exactly the kind of case people forget to write a test for.

Solution

If you want the single-pass form, restore the missing guard so that an absent odd number can never cause a failure:

from math import inf


class Solution:
    def uniformArray(self, nums: list[int]) -> bool:
        min_odd = inf   # smallest odd value
        min_even = inf  # smallest even value
        for x in nums:
            if x % 2:
                min_odd = min(min_odd, x)
            else:
                min_even = min(min_even, x)

        # No odd numbers => everything is even => always constructible.
        if min_odd == inf:
            return True

        # Fails only when an even number is strictly smaller than
        # the smallest odd number.
        return min_even >= min_odd

The added if min_odd == inf: return True line re-introduces exactly the safeguard that the two-pass version got for free via its min_odd != inf check.

Takeaway

When you refactor a multi-pass solution into a single comparison, explicitly verify the sentinel/empty cases (here, inf standing in for "no odd number"). A comparison like min_even >= min_odd behaves differently when one operand is a sentinel value, and that difference is precisely where correctness bugs hide.

Ready to land your dream job?

Unlock your dream job with a 5-minute quiz for a personalized study roadmap!

Get My Roadmap
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Get a Personalized Study Roadmap:

Which of the following array represent a max heap?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More