Sort Array by Parity — Problem Statement & Solution Guide
Problem Description
You are provided with an array of integers representing sensor readings. Your task is to rearrange the array in-place such that all even integers appear before any odd integers. The relative order of the even numbers among themselves and the odd numbers among themselves does not need to be preserved; only the parity-based partitioning is required.
Return the modified array after the rearrangement. The solution must operate with O(1) extra space, modifying the input array directly rather than allocating a new container for the result.
DSA Pattern Breakdown
DSA Pattern Breakdown
"Sort Array by Parity"
WHY DOES IT MATTER?
Parity partitioning is a fundamental example of in‑place data segregation, a skill that appears in sorting, quickselect, and memory management where moving data without extra allocation is critical for performance.
OPTIMIZATION CHALLENGE
The key insight is that you don’t need to know the final order—only the boundary—so you can simultaneously advance from both ends and swap mismatched elements, collapsing the problem to a single linear scan.
REAL-WORLD CONNECTION
Think of a network router that must forward even‑type packets to one lane and odd‑type packets to another; doing this with minimal buffering mirrors the two‑pointer swap strategy, ensuring high throughput with constant memory.
During an interview, start by stating the two‑pointer invariant (all left of left pointer are even, all right of right pointer are odd) and walk through a dry‑run; this demonstrates both correctness and optimality.
COMPLEXITY AT A GLANCE
O(n)O(1)Core Theory — Why This Approach?
The task is a classic partitioning problem where we need to separate elements based on a binary predicate—in this case, parity. A naive solution might iterate through the array and, for each element, shift it to the front or back using extra space or repeated swaps, leading to O(n²) time on large inputs because each insertion can require moving many elements. The optimal paradigm leverages the two‑pointer (or Dutch National Flag) technique: one pointer starts at the beginning looking for an odd number, the other starts at the end looking for an even number, and when both are found they are swapped, guaranteeing each element is examined at most once. This yields linear time with constant extra space, which scales gracefully even for massive sensor streams.
Interview Questions on This Problem
Q1How would you adapt the solution to preserve the original relative order of even and odd numbers?
You would use a stable partition algorithm such as the classic “stable in‑place partition” that employs O(n) extra space (e.g., a temporary buffer) or apply the “rotate” technique to shift blocks, resulting in O(n) time and O(n) auxiliary space.
Q2If the array is read‑only but you can return a new array, what is the most efficient approach?
Traverse the input once, appending evens to a result list followed by odds; this runs in O(n) time and O(n) space, which is optimal for a read‑only constraint.
Q3Can you extend the parity partition to three categories, such as negatives, zeros, and positives, and what changes are needed?
Yes, you can generalize to the Dutch National Flag algorithm with three pointers (low, mid, high) to partition into <0, =0, >0 in a single pass, still O(n) time and O(1) space.
Examples
Input
nums = [3, 1, 2, 4, 5]
Output
[2, 4, 3, 1, 5]
Explanation: Initial array: [3, 1, 2, 4, 5]. 1. Left pointer at index 0 (value 3, odd), right pointer at index 4 (value 5, odd). Move right pointer left. 2. Right pointer at index 3 (value 4, even). Swap index 0 and index 3. Array becomes [4, 1, 2, 3, 5]. Move left pointer right. 3. Left pointer at index 1 (value 1, odd), right pointer at index 2 (value 2, even). Swap index 1 and index 2. Array becomes [4, 2, 1, 3, 5]. Move left pointer right, move right pointer left. 4. Left pointer (index 2) meets right pointer (index 2). Stop. Final array: [4, 2, 1, 3, 5]. All evens (4, 2) are before odds (1, 3, 5).
Input
nums = [2, 2, 2, 11, 13, 3, 1]
Output
[2, 2, 2, 1, 13, 3, 11]
Explanation: Initial array: [2, 2, 2, 11, 13, 3, 1]. 1. Left pointer at index 0 (value 2, even). Move left pointer right. 2. Left pointer at index 1 (value 2, even). Move left pointer right. 3. Left pointer at index 2 (value 2, even). Move left pointer right. 4. Left pointer at index 3 (value 11, odd). Right pointer at index 6 (value 1, odd). Move right pointer left. 5. Right pointer at index 5 (value 3, odd). Move right pointer left. 6. Right pointer at index 4 (value 13, odd). Move right pointer left. 7. Left pointer (index 3) meets right pointer (index 3). Stop. Final array: [2, 2, 2, 11, 13, 3, 1]. Wait, the example output in the prompt was [2, 2, 2, 1, 13, 3, 11]. Let's re-verify a valid swap sequence. Alternative valid output: [2, 2, 2, 1, 13, 3, 11] is also valid. Let's trace a swap that produces this. Start: [2, 2, 2, 11, 13, 3, 1] L=0 (2, even) -> L=1 (2, even) -> L=2 (2, even) -> L=3 (11, odd). R=6 (1, odd) -> R=5 (3, odd) -> R=4 (13, odd) -> R=3 (11, odd). L meets R. No swaps needed. The array is already partitioned? No, 11 is odd and at index 3. The evens are at 0,1,2. The odds are at 3,4,5,6. So [2, 2, 2, 11, 13, 3, 1] is a valid output. Let's provide a different example to ensure clarity. Input: [1, 2, 3, 4, 5, 6] Output: [2, 4, 6, 1, 3, 5] (One possible valid output). Let's stick to the first example's logic for the second example. Input: [1, 2, 3, 4, 5, 6] L=0 (1, odd), R=5 (6, even). Swap 0 and 5. [6, 2, 3, 4, 5, 1]. L=1, R=4. L=1 (2, even). L=2. L=2 (3, odd), R=4 (5, odd). R=3. L=2 (3, odd), R=3 (4, even). Swap 2 and 3. [6, 2, 4, 3, 5, 1]. L=3, R=2. Stop. Output: [6, 2, 4, 3, 5, 1]. Let's use this for Example 2.
Input
nums = [1, 2, 3, 4, 5, 6]
Output
[6, 2, 4, 3, 5, 1]
Explanation: Initial array: [1, 2, 3, 4, 5, 6]. 1. Left pointer at index 0 (value 1, odd), right pointer at index 5 (value 6, even). Swap index 0 and index 5. Array becomes [6, 2, 3, 4, 5, 1]. Move left pointer to index 1, right pointer to index 4. 2. Left pointer at index 1 (value 2, even). Move left pointer to index 2. 3. Left pointer at index 2 (value 3, odd), right pointer at index 4 (value 5, odd). Move right pointer to index 3. 4. Left pointer at index 2 (value 3, odd), right pointer at index 3 (value 4, even). Swap index 2 and index 3. Array becomes [6, 2, 4, 3, 5, 1]. Move left pointer to index 3, right pointer to index 2. 5. Left pointer (index 3) exceeds right pointer (index 2). Stop. Final array: [6, 2, 4, 3, 5, 1]. Evens (6, 2, 4) are at indices 0, 1, 2. Odds (3, 5, 1) are at indices 3, 4, 5.
Constraints
- 1 <= nums.length <= 10^5
- -10^9 <= nums[i] <= 10^9
- The array must be modified in-place.
- Use O(1) extra space.
Optimal Approach & Strategy
Use two pointers at the ends of the original array, swapping mismatched parity values until they cross, achieving O(n) time and O(1) space.
Brute Force Approach
Create a new array, first copy all evens then all odds, which uses O(n) extra space and O(n) time.
Verified Code Solutions
/**
* Sorts the array in-place such that all even integers appear before odd integers.
* Uses two-pointer technique for O(n) time complexity and O(1) space complexity.
*
* @param {number[]} nums - The array of integers to be rearranged.
* @return {number[]} - The modified array after rearrangement.
*/
function sortArrayByParity(nums) {
let left = 0;
let right = nums.length - 1;
while (left < right) {
// Move left pointer forward while current element is even
while (left < right && nums[left] % 2 === 0) {
left++;
}
// Move right pointer backward while current element is odd
while (left < right && nums[right] % 2 !== 0) {
right--;
}
// Swap if left points to odd and right points to even
if (left < right) {
[nums[left], nums[right]] = [nums[right], nums[left]];
left++;
right--;
}
}
return nums;
}
// Example usage
const nums = [3, 1, 2, 4, 5];
const result = sortArrayByParity(nums);
console.log(result);#include <iostream>
#include <vector>
using namespace std;
/**
* Sorts the array in-place such that all even integers appear before odd integers.
* Uses two-pointer technique for O(n) time complexity and O(1) space complexity.
*
* @param nums Reference to the vector of integers to be rearranged.
* @return The modified vector after rearrangement.
*/
vector<int> sortArrayByParity(vector<int>& nums) {
int left = 0;
int right = nums.size() - 1;
while (left < right) {
// Move left pointer forward while current element is even
while (left < right && nums[left] % 2 == 0) {
left++;
}
// Move right pointer backward while current element is odd
while (left < right && nums[right] % 2 != 0) {
right--;
}
// Swap if left points to odd and right points to even
if (left < right) {
swap(nums[left], nums[right]);
left++;
right--;
}
}
return nums;
}
int main() {
// Example usage
vector<int> nums = {3, 1, 2, 4, 5};
vector<int> result = sortArrayByParity(nums);
for (int num : result) {
cout << num << " ";
}
cout << endl;
return 0;
}import java.util.Arrays;
public class Solution {
/**
* Sorts the array in-place such that all even integers appear before odd integers.
* Uses two-pointer technique for O(n) time complexity and O(1) space complexity.
*
* @param nums The array of integers to be rearranged.
* @return The modified array after rearrangement.
*/
public int[] sortArrayByParity(int[] nums) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
// Move left pointer forward while current element is even
while (left < right && nums[left] % 2 == 0) {
left++;
}
// Move right pointer backward while current element is odd
while (left < right && nums[right] % 2 != 0) {
right--;
}
// Swap if left points to odd and right points to even
if (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
return nums;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = {3, 1, 2, 4, 5};
int[] result = solution.sortArrayByParity(nums);
System.out.println(Arrays.toString(result));
}
}from typing import List
def sort_array_by_parity(nums: List[int]) -> List[int]:
"""
Sorts the array in-place such that all even integers appear before odd integers.
Uses two-pointer technique for O(n) time complexity and O(1) space complexity.
Args:
nums: A list of integers to be rearranged.
Returns:
The modified list after rearrangement.
"""
left = 0
right = len(nums) - 1
while left < right:
# Move left pointer forward while current element is even
while left < right and nums[left] % 2 == 0:
left += 1
# Move right pointer backward while current element is odd
while left < right and nums[right] % 2 != 0:
right -= 1
# Swap if left points to odd and right points to even
if left < right:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right -= 1
return nums
# Example usage
if __name__ == "__main__":
nums = [3, 1, 2, 4, 5]
result = sort_array_by_parity(nums)
print(result)/**
* Sorts the array in-place such that all even integers appear before odd integers.
* Uses two-pointer technique for O(n) time complexity and O(1) space complexity.
*
* @param {number[]} nums - The array of integers to be rearranged.
* @return {number[]} - The modified array after rearrangement.
*/
function sortArrayByParity(nums) {
let left = 0;
let right = nums.length - 1;
while (left < right) {
// Move left pointer forward while current element is even
while (left < right && nums[left] % 2 === 0) {
left++;
}
// Move right pointer backward while current element is odd
while (left < right && nums[right] % 2 !== 0) {
right--;
}
// Swap if left points to odd and right points to even
if (left < right) {
[nums[left], nums[right]] = [nums[right], nums[left]];
left++;
right--;
}
}
return nums;
}
// Example usage
const nums = [3, 1, 2, 4, 5];
const result = sortArrayByParity(nums);
console.log(result);Asked in Top Tech Interviews
Solve in Interative Editor
Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.