给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0] 输出: [0,0,1,1,2,2]
大部分人采用的三指针法。
借鉴快排的思想,从左往右扫描,将2放在数组右边,1放在数组左边。三指针,一个指向数组左值、一个指向数组右值、一个指针遍历当前数组。
//当前值==1时, cur++。不作处理.
//当前值==2时,将其和右指针的值交换,右指针--(右半部分是当前指针还未遍历到的地方,其值可能是0,1,2,所以当前cur指针不能++,当元素换过来后继续判断这个换过来的元素。)
//当前值==0时, cur++.将其和左指针交换.(左半部分是cur指针已经遍历过的,l指针其值只会是0/1)
成功
执行用时 : 1 ms, 在Sort Colors的Java提交中击败了91.02% 的用户
内存消耗 : 35.2 MB, 在Sort Colors的Java提交中击败了36.68% 的用户
class Solution {
public void sortColors(int[] nums) {
int l = 0;
int r = nums.length-1;
int cur = 0;
while(l<r && cur<=r){
if(nums[cur] == 1)
cur++;
else if (nums[cur] > 1){
swap(nums, cur, r--);
}
else
swap(nums, cur++, l++);
}
}
private void swap(int[] data, int i, int j){
if(i==j)
return;
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
改进一下,初始化三指针时,跳过左开头为0,和右结尾为2的情况。
成功
执行用时 : 1 ms, 在Sort Colors的Java提交中击败了91.02% 的用户
内存消耗 : 34 MB, 在Sort Colors的Java提交中击败了99.82% 的用户
class Solution {
public void sortColors(int[] nums) {
int l = 0;
int r = nums.length-1;
int cur = 0;
while(r>=0 && nums[r] == 2)
r--;
while(l<nums.length && nums[l] == 0){
cur++;
l++;
}
while(l<r && cur<=r){
if(nums[cur] == 1)
cur++;
else if (nums[cur] > 1)
swap(nums, cur, r--);
else
swap(nums, cur++, l++);
}
}
private void swap(int[] data, int i, int j){
if(i==j)
return;
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}