905. Sort Array by Parity - Explanation
Description
You are given an integer array nums, move all the even integers at the beginning of the array followed by all the odd integers.
Return any array that satisfies this condition.
Example 1:
Input: nums = [3,1,2,4]
Output: [2,4,3,1]Explanation: The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted.
Example 2:
Input: nums = [0]
Output: [0]Constraints:
1 <= nums.length <= 5000.0 <= nums[i] <= 5000.
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Arrays - Basic array traversal and in-place modification
- Two Pointers Technique - Used for optimal O(n) in-place partitioning solutions
- Bit Manipulation Basics - Using bitwise AND (
num & 1) or modulo to check parity (even/odd)
1. Sorting
Intuition
We want all even numbers before odd numbers. By treating the parity (even/odd) as a sort key, we can leverage a built-in sort. Even numbers have parity 0, odd numbers have parity 1, so sorting by parity naturally places evens first.
Algorithm
- Sort the array using a custom comparator based on
num & 1(ornum % 2). - Elements with result
0(even) come before elements with result1(odd). - Return the sorted array.
Time & Space Complexity
- Time complexity:
- Space complexity: or depending on the sorting algorithm.
2. Array
Intuition
Instead of sorting, we can separate elements into two groups in a single pass. Collect all even numbers in one list and all odd numbers in another, then concatenate them. This avoids the overhead of comparison-based sorting.
Algorithm
- Create two lists: one for even numbers, one for odd numbers.
- Iterate through the array and add each element to the appropriate list based on its parity.
- Concatenate the even list followed by the odd list.
- Copy the result back into the original array (or return the concatenated result).
Time & Space Complexity
- Time complexity:
- Space complexity:
3. Two Pointers - I
Intuition
We can partition the array in-place using two pointers at opposite ends. The left pointer finds odd numbers that need to move right, and the right pointer marks where odd numbers should go. When we find an odd number on the left, we swap it with whatever is on the right, effectively pushing odd numbers to the end.
Algorithm
- Initialize two pointers:
iat the start,jat the end. - While
i < j:- If
nums[i]is odd, swap it withnums[j]and decrementj. - Otherwise, increment
i(the element is even and already in place).
- If
- Return the modified array.
Time & Space Complexity
- Time complexity:
- Space complexity: extra space.
4. Two Pointers - II
Intuition
This approach uses a slow and fast pointer moving in the same direction. The slow pointer l tracks where the next even number should be placed. The fast pointer r scans through the array. Whenever we find an even number, we swap it to position l and advance l. This collects all even numbers at the front.
Algorithm
- Initialize a slow pointer
lat0. - Iterate through the array with a fast pointer
r:- If
nums[r]is even, swapnums[l]withnums[r]and incrementl.
- If
- Return the modified array.
Time & Space Complexity
- Time complexity:
- Space complexity: extra space.
Common Pitfalls
Incrementing the Pointer After Swapping with the Right Boundary
In the two-pointer approach where you swap odd elements to the right, you must not increment the left pointer after a swap. The element swapped from the right side has not been checked yet and could be odd, requiring another swap.
Using Modulo on Negative Numbers
While this problem only has non-negative integers, using num % 2 can behave unexpectedly with negative numbers in some languages (returning -1 instead of 1 for odd negatives). Using bitwise AND (num & 1) is safer and more efficient for parity checking.
Sign in to join the discussion