荷兰国旗问题解法 (推荐这种解法)
这是荷兰三色问题,把一个数组用一个数num划分为三个部分,左边是小于num的数组元素,中间是等于num的数组元素,右边是大于num的数组元素。
设三个指针left,right,index。left指向数组之前,right指向数组之后,用index遍历整个数组与num比较,直到index等于right。
当nums[index]小于num,把他与left后面的数交换,然后index遍历下一个数,left右移。nums[index]等于num,index遍历下一个数。nums[index]大于num,把它与right前面的数交换,right左移。left指向的数始终是小于num的,right指向的数始终是大于num的。
class Solution {
public void sortColors(int[] nums) {
int left = -1, right = nums.length, index = 0;
while(index != right){
if(nums[index] < 1){
swap(nums,index++,++left);
}else if(nums[index] == 1){
index++;
}else{
swap(nums,index,--right);
}
}
}
public void swap(int[] nums, int i, int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
快速排序
class Solution {
public void sortColors(int[] nums) {
process(nums,0,nums.length-1);
}
public void process(int[] nums, int left, int right){
if(left >= right){
return ;
}
int l = left;
int r = right;
int tmp = nums[left];
while(left != right){
while(nums[right] >= tmp && right > left){
right--;
}
while(nums[left] <= tmp && right > left){
left++;
}
if(right > left){
int exchange = nums[right];
nums[right] = nums[left];
nums[left] = exchange;
}
}
//当left,right相遇时nums[left]一定是小于等于tmp的
//交换nums[left]和nums[l];
nums[l] = nums[left];
nums[left] = tmp;
process(nums,l,left-1);
process(nums,left+1,r);
}
}
使用计数排序的两趟扫描算法
class Solution {
public void sortColors(int[] nums) {
int rsum = 0, wsum = 0, bsum = 0;
for(int i = 0; i < nums.length; i++){
if(nums[i] == 0){
rsum++;
}else if(nums[i] == 1){
wsum++;
}else if(nums[i] == 2){
bsum++;
}
}
for(int i = 0; i < nums.length; i++){
if(i < rsum){
nums[i] = 0;
}else if(i < rsum+wsum){
nums[i] = 1;
}else if(i <nums.length){
nums[i] = 2;
}
}
}
}