Facebook Pixel

905. Sort Array By Parity

Problem Description

You are given an integer array nums. Your task is to rearrange the array so that all even integers appear before all odd integers.

The problem asks you to move all even numbers to the beginning of the array, followed by all odd numbers. The order of even numbers among themselves doesn't matter, and the same applies to odd numbers. You just need to ensure that the array is partitioned into two sections: evens first, then odds.

For example:

  • If nums = [3, 1, 2, 4], a valid output could be [2, 4, 3, 1] or [4, 2, 1, 3]
  • The key requirement is that all even numbers (2 and 4) come before all odd numbers (3 and 1)

You need to return any array that satisfies this condition - there can be multiple correct answers since the relative order within even and odd groups doesn't matter.

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

Intuition

The key insight is that we need to partition the array into two groups: evens and odds. This is similar to the classic partitioning problem where we want to separate elements based on a condition.

Think about it this way: we want all evens on the left side and all odds on the right side. We can use two pointers starting from opposite ends of the array. The left pointer (i) will look for odd numbers that are in the "wrong" position (they should be on the right), and the right pointer (j) will look for even numbers that are in the "wrong" position (they should be on the left).

When we find an odd number on the left (where evens should be) and an even number on the right (where odds should be), we've found two elements that are both in the wrong sections. By swapping them, we fix both positions at once.

The beauty of this approach is that we're working from both ends toward the middle:

  • If the left element is already even, it's in the correct position, so we move the left pointer forward
  • If the right element is already odd, it's in the correct position, so we move the right pointer backward
  • When we find a misplaced pair (odd on left, even on right), we swap them and move both pointers

This way, we only need to traverse the array once, making it an efficient O(n) solution with O(1) extra space since we're modifying the array in-place.

Learn more about Two Pointers and Sorting patterns.

Solution Approach

We implement the two-pointer technique to partition the array in-place. Here's how the algorithm works:

  1. Initialize two pointers: Set i = 0 pointing to the start of the array and j = len(nums) - 1 pointing to the end.

  2. Process elements while pointers haven't crossed (i < j):

    • Case 1: If nums[i] % 2 == 0 (even number at left position)
      • This element is already in the correct section, so increment i by 1 to check the next element
    • Case 2: If nums[j] % 2 == 1 (odd number at right position)
      • This element is already in the correct section, so decrement j by 1 to check the previous element
    • Case 3: If neither of the above conditions is true
      • This means nums[i] is odd (should be on the right) and nums[j] is even (should be on the left)
      • Swap nums[i] and nums[j] to place both elements in their correct sections
      • Move both pointers: increment i by 1 and decrement j by 1
  3. Return the modified array: After the loop completes, all even numbers will be on the left side and all odd numbers on the right side.

The algorithm efficiently partitions the array with a single pass, achieving O(n) time complexity where n is the length of the array. The space complexity is O(1) since we only use two pointer variables and modify the array in-place.

Ready to land your dream job?

Unlock your dream job with a 3-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [3, 1, 2, 4]:

Initial State:

  • Array: [3, 1, 2, 4]
  • i = 0 (pointing to 3)
  • j = 3 (pointing to 4)

Step 1: Check i < j (0 < 3) โœ“

  • nums[0] = 3 is odd (3 % 2 = 1) - not even, so Case 1 doesn't apply
  • nums[3] = 4 is even (4 % 2 = 0) - not odd, so Case 2 doesn't apply
  • Both elements are misplaced! Case 3: Swap them
  • After swap: [4, 1, 2, 3]
  • Move pointers: i = 1, j = 2

Step 2: Check i < j (1 < 2) โœ“

  • nums[1] = 1 is odd (1 % 2 = 1) - not even, so Case 1 doesn't apply
  • nums[2] = 2 is even (2 % 2 = 0) - not odd, so Case 2 doesn't apply
  • Both elements are misplaced! Case 3: Swap them
  • After swap: [4, 2, 1, 3]
  • Move pointers: i = 2, j = 1

Step 3: Check i < j (2 < 1) โœ—

  • The pointers have crossed, so we stop

Final Result: [4, 2, 1, 3]

  • Even numbers (4, 2) are on the left
  • Odd numbers (1, 3) are on the right
  • The partitioning is complete!

The algorithm successfully partitioned the array with just 2 swaps, placing all even integers before all odd integers.

Solution Implementation

1class Solution:
2    def sortArrayByParity(self, nums: List[int]) -> List[int]:
3        """
4        Sorts array so that all even numbers appear before odd numbers.
5        Uses two-pointer technique to swap elements in-place.
6      
7        Args:
8            nums: List of integers to be sorted by parity
9          
10        Returns:
11            The modified array with even numbers first, then odd numbers
12        """
13        # Initialize two pointers: left starts at beginning, right at end
14        left = 0
15        right = len(nums) - 1
16      
17        # Continue until pointers meet
18        while left < right:
19            # If left element is even, it's in correct position, move left pointer forward
20            if nums[left] % 2 == 0:
21                left += 1
22            # If right element is odd, it's in correct position, move right pointer backward
23            elif nums[right] % 2 == 1:
24                right -= 1
25            # If left is odd and right is even, swap them and move both pointers
26            else:
27                nums[left], nums[right] = nums[right], nums[left]
28                left += 1
29                right -= 1
30              
31        return nums
32
1class Solution {
2    /**
3     * Sorts an array by parity, placing all even numbers before odd numbers.
4     * Uses two-pointer technique to partition the array in-place.
5     * 
6     * @param nums The input array to be sorted by parity
7     * @return The modified array with even numbers first, then odd numbers
8     */
9    public int[] sortArrayByParity(int[] nums) {
10        // Initialize two pointers: left starts at beginning, right at end
11        int left = 0;
12        int right = nums.length - 1;
13      
14        // Continue until the two pointers meet
15        while (left < right) {
16            // If left element is even, it's already in correct position
17            if (nums[left] % 2 == 0) {
18                left++;
19            } 
20            // If right element is odd, it's already in correct position
21            else if (nums[right] % 2 == 1) {
22                right--;
23            } 
24            // Left is odd and right is even, so swap them
25            else {
26                // Swap elements at left and right positions
27                int temp = nums[left];
28                nums[left] = nums[right];
29                nums[right] = temp;
30              
31                // Move both pointers inward after successful swap
32                left++;
33                right--;
34            }
35        }
36      
37        return nums;
38    }
39}
40
1class Solution {
2public:
3    vector<int> sortArrayByParity(vector<int>& nums) {
4        // Use two pointers approach: left pointer starts from beginning, right from end
5        int left = 0;
6        int right = nums.size() - 1;
7      
8        // Continue until the two pointers meet
9        while (left < right) {
10            // If left element is even, it's already in correct position, move left pointer forward
11            if (nums[left] % 2 == 0) {
12                ++left;
13            }
14            // If right element is odd, it's already in correct position, move right pointer backward
15            else if (nums[right] % 2 == 1) {
16                --right;
17            }
18            // If left element is odd and right element is even, swap them and move both pointers
19            else {
20                swap(nums[left], nums[right]);
21                ++left;
22                --right;
23            }
24        }
25      
26        return nums;
27    }
28};
29
1/**
2 * Sorts an array by parity - moves all even numbers to the front and odd numbers to the back
3 * @param nums - The input array of numbers to be sorted by parity
4 * @returns The same array with even numbers at the beginning and odd numbers at the end
5 */
6function sortArrayByParity(nums: number[]): number[] {
7    // Initialize two pointers: left pointer starts from beginning, right pointer from end
8    let leftIndex: number = 0;
9    let rightIndex: number = nums.length - 1;
10  
11    // Continue until the two pointers meet
12    while (leftIndex < rightIndex) {
13        // Check if the left element is even
14        if (nums[leftIndex] % 2 === 0) {
15            // Even number is already in correct position, move left pointer forward
16            leftIndex++;
17        } 
18        // Check if the right element is odd
19        else if (nums[rightIndex] % 2 === 1) {
20            // Odd number is already in correct position, move right pointer backward
21            rightIndex--;
22        } 
23        // Left element is odd and right element is even - need to swap
24        else {
25            // Swap the elements using destructuring assignment
26            [nums[leftIndex], nums[rightIndex]] = [nums[rightIndex], nums[leftIndex]];
27            // Move both pointers inward after swapping
28            leftIndex++;
29            rightIndex--;
30        }
31    }
32  
33    // Return the modified array
34    return nums;
35}
36

Time and Space Complexity

The time complexity is O(n), where n is the length of the array nums. This is because the algorithm uses a two-pointer approach where pointer i starts from the beginning and pointer j starts from the end of the array. In each iteration, at least one pointer moves closer to the other (either i increments, j decrements, or both move when a swap occurs). Since the pointers converge and each element is visited at most once, the total number of operations is proportional to n.

The space complexity is O(1). The algorithm only uses a constant amount of extra space for the two pointer variables i and j, regardless of the input size. The sorting is done in-place by swapping elements within the original array, so no additional arrays or data structures that scale with input size are created.

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

Common Pitfalls

1. Incorrect Pointer Movement After Swap

A common mistake is moving only one pointer or forgetting to move pointers after swapping elements. This can lead to infinite loops or incorrect results.

Incorrect Implementation:

while left < right:
    if nums[left] % 2 == 0:
        left += 1
    elif nums[right] % 2 == 1:
        right -= 1
    else:
        nums[left], nums[right] = nums[right], nums[left]
        # Forgot to move pointers! This causes infinite loop

Solution: Always move both pointers after a swap since you know both elements are now correctly positioned.

2. Using <= Instead of < in While Condition

Using while left <= right instead of while left < right can cause unnecessary operations when pointers meet at the same index.

Why it matters: When left == right, we're looking at the same element, and no swap is needed. The element is already in its final position regardless of whether it's even or odd.

Correct approach: Use while left < right to stop when pointers meet or cross.

3. Checking Only One Condition Before Swapping

Some implementations might check only if the left element is odd before swapping, assuming the right element must be even:

Incorrect Implementation:

while left < right:
    if nums[left] % 2 == 1:  # Only checking if left is odd
        nums[left], nums[right] = nums[right], nums[left]
        left += 1
        right -= 1
    else:
        left += 1

Problem: This doesn't account for when the right element is also odd. You'd swap two odd numbers unnecessarily and might miss even numbers on the right side.

Solution: Check both conditions separately (even on left, odd on right) before deciding to swap, as shown in the original solution.

4. Modifying Pointer Variables in Multiple Places

Incrementing or decrementing pointers in multiple places within the same iteration can lead to skipping elements or going out of bounds:

Incorrect Implementation:

while left < right:
    if nums[left] % 2 == 0:
        left += 1
    if nums[right] % 2 == 1:  # Should be 'elif', not 'if'
        right -= 1
    # This could move both pointers even when no swap occurs
    nums[left], nums[right] = nums[right], nums[left]
    left += 1
    right -= 1

Solution: Use if-elif-else structure to ensure only one action is taken per iteration, making the logic clear and preventing pointer manipulation errors.

Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

Which of the tree traversal order can be used to obtain elements in a binary search tree in sorted order?


Recommended Readings

Want a Structured Path to Master System Design Too? Donโ€™t Miss This!

Load More