Sort Array By Parity II
EasyPrompt
Given an array of integers nums, half of the integers in nums are odd, and the other half are even.
Sort the array so that whenever nums[i] is odd, i is odd, and whenever nums[i] is even, i is even.
Return any answer array that satisfies this condition.
Example 1:
Input: nums = [4,2,5,7]
Output: [4,5,2,7]
Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also have been accepted.Example 2:
Input: nums = [2,3]
Output: [2,3]
Constraints:
2 <= nums.length <= 2 * 104nums.lengthis even.- Half of the integers in
numsare even. 0 <= nums[i] <= 1000
Follow Up: Could you solve it in-place?
Approaches
2 approaches with complexity analysis and trade-offs.
A straightforward approach is to use an additional array to store the sorted elements. We can iterate through the input array, and based on the parity of each number, place it in the correct position in the new array.
Algorithm
- Create a new integer array
resultwith the same length asnums. - Initialize an
evenIndexpointer to0. - Initialize an
oddIndexpointer to1. - Iterate through each
numin the input arraynums. - If
numis even (i.e.,num % 2 == 0), assignresult[evenIndex] = numand updateevenIndex = evenIndex + 2. - If
numis odd, assignresult[oddIndex] = numand updateoddIndex = oddIndex + 2. - After the loop finishes, return the
resultarray.
Walkthrough
We can solve this problem by allocating a new array, result, of the same size as the input nums. We'll use two index pointers: evenIndex starting at 0 for placing even numbers, and oddIndex starting at 1 for placing odd numbers.
We then iterate through each number in the input array nums.
- If the number is even, we place it at
result[evenIndex]and then incrementevenIndexby 2. - If the number is odd, we place it at
result[oddIndex]and then incrementoddIndexby 2. After iterating through all the numbers innums, theresultarray will be sorted according to the problem's criteria.
class Solution { public int[] sortArrayByParityII(int[] nums) { int n = nums.length; int[] result = new int[n]; int evenIndex = 0; int oddIndex = 1; for (int num : nums) { if (num % 2 == 0) { result[evenIndex] = num; evenIndex += 2; } else { result[oddIndex] = num; oddIndex += 2; } } return result; }}Complexity
Time
O(N), where `N` is the number of elements in the array. We perform a single pass through the input array.
Space
O(N), as we use an auxiliary array of size `N` to store the result.
Trade-offs
Pros
The logic is simple and easy to follow.
Implementation is straightforward.
Cons
It's not an in-place solution and requires extra memory, which can be a drawback for very large inputs.
To solve the problem in-place as suggested by the follow-up, we can use a two-pointer technique. One pointer, even, will iterate through the even indices, and another pointer, odd, will iterate through the odd indices. The goal is to find and swap misplaced elements.
Algorithm
- Initialize a pointer
evento0and a pointeroddto1. - Enter a loop that continues as long as both
evenandoddare within the array bounds (< nums.length). - Inside the loop, advance the
evenpointer by 2 until it points to an odd number (nums[even] % 2 != 0) or goes out of bounds. - Similarly, advance the
oddpointer by 2 until it points to an even number (nums[odd] % 2 == 0) or goes out of bounds. - If both pointers are still within the array bounds, it means we've found an odd number at an even index and an even number at an odd index. Swap
nums[even]andnums[odd]. - The loop continues until one of the pointers moves past the end of the array, at which point the array is correctly sorted.
- Return the modified
numsarray.
Walkthrough
This approach modifies the array directly without using extra space. We use two pointers: even starting at index 0 and odd starting at index 1.
The even pointer's job is to find the first even index i that holds an odd number (nums[i] % 2 != 0). It does this by advancing by 2 in each step (even += 2).
Similarly, the odd pointer's job is to find the first odd index j that holds an even number (nums[j] % 2 == 0). It also advances by 2 in each step (odd += 2).
Once both pointers have found a misplaced number, we swap nums[even] and nums[odd]. This places the even number at an even index and the odd number at an odd index, correcting their positions.
We repeat this process until either pointer goes beyond the array's bounds. Since the input is guaranteed to have an equal number of even and odd numbers, this process will correctly sort the entire array.
class Solution { public int[] sortArrayByParityII(int[] nums) { int n = nums.length; int even = 0; int odd = 1; while (even < n && odd < n) { // Find the first even index with an odd number while (even < n && nums[even] % 2 == 0) { even += 2; } // Find the first odd index with an even number while (odd < n && nums[odd] % 2 != 0) { odd += 2; } // If both pointers are valid, swap the elements if (even < n && odd < n) { int temp = nums[even]; nums[even] = nums[odd]; nums[odd] = temp; } } return nums; }}Complexity
Time
O(N), where `N` is the number of elements. Although there are nested loops, each pointer (`even` and `odd`) traverses its respective set of indices (even or odd) at most once. Therefore, each element is visited a constant number of times.
Space
O(1). The sorting is performed in-place, so no additional space proportional to the input size is required.
Trade-offs
Pros
Highly efficient in terms of space, satisfying the in-place requirement.
Maintains a linear time complexity.
Cons
The logic with two pointers and nested loops can be slightly more complex to reason about compared to the auxiliary array method.
Solutions
Solution
class Solution {public int[] sortArrayByParityII(int[] nums) { for (int i = 0, j = 1; i < nums.length; i += 2) { if ((nums[i] & 1) == 1) { while ((nums[j] & 1) == 1) { j += 2; } int t = nums[i]; nums[i] = nums[j]; nums[j] = t; } } return nums; }}/** * @param {number[]} nums * @return {number[]} */ var sortArrayByParityII = function (nums) { for (let i = 0, j = 1; i < nums.length; i += 2) { if ((nums[i] & 1) == 1) { while ((nums[j] & 1) == 1) { j += 2; } [nums[i], nums[j]] = [nums[j], nums[i]]; } } return nums; };class Solution {public: vector<int> sortArrayByParityII(vector<int> &nums) { for (int i = 0, j = 1; i < nums.size(); i += 2) { if ((nums[i] & 1) == 1) { while ((nums[j] & 1) == 1) { j += 2; } swap(nums[i], nums[j]); } } return nums; }};class Solution: def sortArrayByParityII(self, nums: List[int]) -> List[int]: n, j = len(nums), 1 for i in range(0, n, 2): if (nums[i] & 1) == 1: while (nums[j] & 1) == 1: j += 2 nums[i], nums[j] = nums[j], nums[i] return numsVideo walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.