颜色分类
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
必须在不使用库的sort函数的情况下解决这个问题。
示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例 2:
输入:nums = [2,0,1]
输出:[0,1,2]
(上述题目来源于LeetCode)
解法一(冒泡排序)
class Solution {
public void bubbleSort(int[] list){
//冒泡排序
boolean changed = true;
do{
changed = false;
for(int i = 0;i < list.length - 1;i++){
if(list[i] > list[i+1]){
int temp = list[i];
list[i] = list[i+1];
list[i+1] = temp;
changed = true;
}
}
}while(changed);
}
public void sortColors(int[] nums) {
bubbleSort(nums);
}
}
解法二(快速排序)
class Solution {
//快速排序
public void quickSort(int []list,int low,int high){
if(low > high){
return;
}
int i = low;
int j = high;
int swap = list[low];
while(i < j){
while(list[j] >= swap && i < j){
j--;
}
while(list[i] <= swap && i < j){
i++;
}
if(i < j){
int temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
list[low] = list[i];
list[i] = swap;
quickSort(list,low,i-1);
quickSort(list,i+1,high);
}
public void sortColors(int[] nums) {
quickSort(nums,0,nums.length-1);
}
}
解法三(单指针,两次遍历)
class Solution {
public void sortColors(int[] nums) {
//单指针,两次遍历
//先将所有0移到最前面,再将1移到0后面
int cur = 0;
int n = nums.length;
//第一次遍历,将0移到最前面
for(int i = 0;i < n;i++){
if(nums[i] == 0){
int temp = nums[cur];
nums[cur] = nums[i];
nums[i] = temp;
cur++;
}
}
//第二次遍历,将1移到0后面
for(int i = cur;i < n;i++){
if(nums[i] == 1){
int temp = nums[cur];
nums[cur] = nums[i];
nums[i] = temp;
cur++;
}
}
}
}
解法四(双指针)
class Solution {
public void sortColors(int[] nums) {
//双指针
int left = 0;
int right = nums.length - 1;
for(int i = 0;i <= right;i++){
if(left > right){
break;
}
while(nums[i] == 2 && i <= right){
int temp = nums[right];
nums[right] = nums[i];
nums[i] = temp;
right--;
}
if(nums[i] == 0){
int temp = nums[left];
nums[left] = nums[i];
nums[i] = temp;
left++;
}
}
}
}