905. Sort Array By Parity
Problem Description
The LeetCode problem at hand requires us to rearrange the elements of a given integer array nums
. The task is to move all even numbers to the front (beginning) of the array and place all odd numbers towards the rear (end) of the array. It's important to note that the problem does not require the numbers to be sorted within the even or odd groups, which means that the relative order between the even or odd elements does not matter. We just need to ensure that all the even integers appear before any odd integer in the resulting array. There are no constraints for the order of elements within their respective groups (even or odd), and thus any configuration that satisfies the condition will count as a correct answer.
Intuition
The solution to this problem is built on the two-pointer technique. We strategically place two pointers (i
and j
) at the start and end of the array respectively. The idea is to increment i
(the left pointer) until we find an odd number and decrement j
(the right pointer) until we find an even number. When both conditions are met, we have an odd number at the left pointer and an even number at the right pointer, and we swap them. This is based on the intuition that even numbers should be at the front and odd numbers at the back.
By incrementing and decrementing the pointers only when the even/odd conditions are not met, we ensure the pointers will eventually scan through the whole array. The process continues until the two pointers meet or cross each other, which indicates all even elements have been moved ahead of the odd elements. We use bitwise AND, nums[i] & 1
, to quickly determine if a number is odd (if the operation results in 1
) or even (if it results in 0
). After finishing the algorithm, we return the modified array which now has all even integers at the beginning followed by odd integers.
Learn more about Two Pointers and Sorting patterns.
Solution Approach
The implementation of the solution leverages the two-pointer technique, which is a common pattern used for array manipulation problems. This technique helps us to work with two different positions of the array simultaneously. Here's the breakdown of the steps involved, using the algorithm shown in the Reference Solution Approach:
-
Initialize two pointers
i
at0
(start of the array) andj
atlen(nums) - 1
(end of the array). This is where we will begin our processing from both ends of the array. -
Loop through the array using a
while
loop that runs as long asi < j
. This condition ensures that we keep processing until both pointers meet or cross, which means we have compared all elements. -
Inside the loop:
-
We check if
nums[i]
is odd by usingnums[i] & 1
. Using the bitwise AND operation with1
gives a result of1
if the last bit is1
(which means the number is odd), and0
otherwise (which means the number is even). -
If
nums[i]
is odd, we need to move this number towards the end of the array. We swapnums[i]
withnums[j]
(the current element at the pointer from the end of the array) using the tuple unpacking syntaxnums[i], nums[j] = nums[j], nums[i]
. -
After swapping, we decrement
j
by1
(j -= 1
) to move the end pointer one step to the left, as we've just placed an odd number in its correct position towards the end. -
If
nums[i]
is not odd (i.e., it's even), we simply incrementi
by1
(i += 1
) to continue the loop and look for the next odd number, as even numbers are already in their correct position at the start of the array.
-
-
The loop continues until
i
is no longer less thanj
, at which point we've achieved our goal of moving all even numbers to the front and all odd numbers to the end of the array. -
Finally, we return the modified array
nums
.
This approach efficiently uses the two-pointer technique without the need for extra space (except for a few temporary variables), and it operates directly on the input array, resulting in an in-place algorithm. Since each element is looked at most once, the time complexity of this solution is O(n), where n is the number of elements in the array.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's consider the array nums = [3, 8, 5, 13, 6, 12, 4, 1]
and walk through the solution approach detailed above using this example.
-
We initialize two pointers
i
at0
(start of the array) andj
atlen(nums) - 1
, which is7
in this case. -
We start our
while
loop with the conditioni < j
. Initially,i
is0
andj
is7
. -
Inside the
while
loop:- We check
nums[i] & 1
to determine ifnums[i]
is odd. - For
nums[0]
, which is3
, we find it to be odd (3 & 1
equals1
). - We swap
nums[i]
withnums[j]
, so now our array looks like this:[1, 8, 5, 13, 6, 12, 4, 3]
. - We then decrement
j
by1
, soj
now equals6
.
- We check
-
The next iteration starts with
i = 0
andj = 6
:nums[i]
is now1
, which is odd (1 & 1
equals1
).- We swap
nums[i]
withnums[j]
, leading to:[4, 8, 5, 13, 6, 12, 1, 3]
. - We again decrement
j
by1
, andj
is now5
.
-
We continue the loop:
- Now,
nums[i]
is4
. It's even (4 & 1
equals0
) so we don't swap. We just incrementi
by1
, resulting ini = 1
. - During the same iteration,
nums[1]
is8
, which is also even. Soi
is incremented again toi = 2
.
- Now,
-
With
i = 2
andj = 5
, the loop continues:nums[2]
is5
, which is odd.- We swap
nums[2]
withnums[5]
, making the array[4, 8, 12, 13, 6, 5, 1, 3]
. - We decrement
j
to4
.
-
We iterate further:
i
is2
, andj
is4
.- For
i = 2
,nums[i]
is12
(even), so we incrementi
to3
. - No swap needed as
nums[i]
is now13
(odd) andnums[j]
is6
(even).
-
With
i = 3
andj = 4
, we perform our last iteration:- We find
nums[3]
is odd, so we swapnums[3]
andnums[4]
, resulting in[4, 8, 12, 6, 13, 5, 1, 3]
. - We decrement
j
to3
.
- We find
-
At this point,
i
equalsj
. According to our loop conditioni < j
, the loop terminates. -
We have successfully moved all even numbers to the front and all odd numbers to the end of the array.
The resulting array is [4, 8, 12, 6, 13, 5, 1, 3]
, which meets the requirements of the problem. This example demonstrates how the two-pointer technique applied in this algorithm effectively separates even and odd numbers within a single pass through the array without the need for any additional space, adhering to a linear time complexity O(n).
Solution Implementation
1class Solution:
2 def sortArrayByParity(self, nums: List[int]) -> List[int]:
3 # Initialize two pointers, left at the start of the list and right at the end
4 left, right = 0, len(nums) - 1
5
6 # Loop through the array until the two pointers meet
7 while left < right:
8 # If the number at the current left pointer is odd,
9 # we swap it with the number at the right pointer.
10 if nums[left] % 2 == 1:
11 # Swap the elements at left and right pointers
12 nums[left], nums[right] = nums[right], nums[left]
13 # Move the right pointer inwards, since we've placed an odd number at the end
14 right -= 1
15 else:
16 # If the number at the left pointer is even, we move the left pointer inwards
17 left += 1
18
19 # Return the array which is now sorted by parity:
20 # Even numbers at the front, odd numbers at the back
21 return nums
22
1class Solution {
2
3 // This function takes an integer array 'nums' and returns an array
4 // with all even integers followed by all odd integers.
5 public int[] sortArrayByParity(int[] nums) {
6 // Initialize two pointers: 'left' starting from the beginning and 'right' from the end of the array.
7 int left = 0, right = nums.length - 1;
8
9 // Continue until 'left' pointer is less than 'right' pointer.
10 while (left < right) {
11 // If the element at 'left' index is odd, swap it with the element at 'right' index.
12 if (nums[left] % 2 == 1) {
13 // Perform the swap of elements.
14 int temp = nums[left];
15 nums[left] = nums[right];
16 nums[right] = temp;
17
18 // Decrement 'right' pointer as we have moved an odd number to the correct side of array.
19 right--;
20 } else {
21 // Increment 'left' pointer if the current element is even,
22 // as it is already in the correct side of array.
23 left++;
24 }
25 }
26 // Return the rearranged array with all even numbers first followed by odd numbers.
27 return nums;
28 }
29}
30
1#include <vector> // Include the header for vector
2using namespace std;
3
4class Solution {
5public:
6 vector<int> sortArrayByParity(vector<int>& nums) {
7 // Initialize two pointers.
8 // 'left' for the start of the array.
9 // 'right' for the end of the array.
10 int left = 0, right = nums.size() - 1;
11
12 // Loop until the two pointers meet.
13 while (left < right) {
14 // If the current element at 'left' is odd,
15 // swap it with the element at 'right' and move 'right' backwards.
16 if (nums[left] % 2 == 1) {
17 swap(nums[left], nums[right]);
18 --right;
19 } else {
20 // If the element is even, move 'left' forward.
21 ++left;
22 }
23 }
24
25 // Return the modified vector, which is sorted by parity.
26 return nums;
27 }
28};
29
1/**
2 * Sorts the array such that even numbers come before odd numbers,
3 * and even and odd numbers each maintain their relative ordering.
4 *
5 * @param {number[]} nums - The array of numbers to be sorted.
6 * @return {number[]} The sorted array.
7 */
8function sortArrayByParity(nums: number[]): number[] {
9 let leftIndex: number = 0; // Index starting from the beginning of the array
10 let rightIndex: number = nums.length - 1; // Index starting from the end of the array
11
12 // Continue until the left index is no longer less than the right index
13 while (leftIndex < rightIndex) {
14 // Check if the current element at the left index is odd
15 if (nums[leftIndex] % 2 !== 0) {
16 // Swap the odd number from the beginning with the element at the right index
17 [nums[leftIndex], nums[rightIndex]] = [nums[rightIndex], nums[leftIndex]];
18 rightIndex--; // Move the right index one step to the left
19 } else {
20 leftIndex++; // If it's an even number, move the left index one step to the right
21 }
22 }
23
24 return nums; // Return the reordered array
25}
26
27// The function can now be exported and used in other TypeScript modules
28export { sortArrayByParity };
29
Time and Space Complexity
The provided code has a time complexity of O(n)
where n
is the length of the input list nums
. This is because each element in the list is visited at most once by either the i
or j
pointers which move towards each other from opposite ends of the list.
The space complexity of the code is O(1)
because it sorts the array in place without using any extra space proportional to the input size. Only a constant amount of additional memory space is used for the index variables i
and j
.
Learn more about how to find time and space complexity quickly using problem constraints.
What is the best way of checking if an element exists in an unsorted array once in terms of time complexity? Select the best that applies.
Recommended Readings
Tech Interview Pattern Two Pointers Introduction If you prefer videos here's a super quick introduction to Two Pointers div class responsive iframe iframe src https www youtube com embed xZ4AfXHQ1VQ title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture allowfullscreen iframe div Two pointers is a common interview
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Want a Structured Path to Master System Design Too? Don’t Miss This!