Given an array nums with n objects colored red, white, or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white, and blue.
LeetCode-75: Given an array nums
with n
objects colored red, white, or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white, and blue.
We will use the integers 0
, 1
, and 2
to represent the color red, white, and blue, respectively. You must solve this problem without using the library’s sort function.
The simplest approach to solve this problem is to count the number of 0
, 1
, and 2
in the array and then fill the array with the count of 0
, 1
, and 2
respectively. This approach will take $O(n)$ time and $O(1)$ space.
Here is a Java implementation of the above approach:
public void sortColors(int[] nums) {
int start = 0;
Map<Integer, Long> freqMap = Arrays.stream(nums)
.boxed()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()));
for (int i = 0; i <= 2; i++) {
// fill the array with the count of i
// use a default value of 0 if the key is not present in the map
int end = start + freqMap.getOrDefault(i, 0L).intValue();
int value = i;
IntStream.range(start, end).forEach(index -> nums[index] = value);
start = end;
}
}
The above approach is not optimal as it requires two passes over the array. We can solve this problem in a single pass using the two-pointer approach known as the Dutch National Flag problem given by Edsger W. Dijkstra.
The approach is based on the following observations:
0
, 1
, 2
and unknown
.
0
region is from 0
to low-1
i.e. all the elements from index 0
to low-1
should be 0
.1
region is from low
to mid-1
i.e. all the elements from index low
to mid-1
should be 1
.2
region is from high+1
to n-1
i.e. all the elements from index high+1
to n-1
should be 2
.unknown
region is from mid
to high
i.e. all the elements from index mid
to high
are yet to be processed.On a high level, this is done by the following steps:
low
, mid
, and high
to 0
, 0
, and n-1
respectively.mid
is less than or equal to high
.mid
is 0
, swap the element at low
and mid
and increment both low
and mid
.mid
is 1
, increment mid
.mid
is 2
, swap the element at mid
and high
and decrement high
.mid
is less than or equal to high
.Here is the a implementation of the above approach:
public void sortColors(int[] nums) {
int low = 0, mid = 0, high = nums.length -1;
while(mid <= high){
// if nums[mid] is 0, swap nums[low] and nums[mid] and increment low and mid
// i.e. populate the 0 region
if(nums[mid] == 0){
int temp = nums[low];
nums[low] = nums[mid];
nums[mid] = temp;
mid++;
low++;
}
// if nums[mid] is 2, swap nums[high] and nums[mid] and decrement high
// i.e. populate the 2 region
else if(nums[mid] == 2){
int temp = nums[high];
nums[high] = nums[mid];
nums[mid] = temp;
high--;
}
// if nums[mid] is 1, increment mid
// i.e. populate the 1 region
else{
mid++;
}
}
}
The time complexity of the above approach is $O(n)$ as we are iterating over the array only once. The space complexity is $O(1)$ as we are not using any extra space.
Be notified of new posts. Subscribe to the RSS feed.