LeetCode75 SortColors

LeetCode75 SortColors

题目描述

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

解答

解法一:计数排序

第一趟遍历,计算出0,1,2的个数,然后按照0,1,2出现的个数重写当前数组。

public static void solve1(int[] nums){
        int[] count= new int[3];
        for(int i=0;i<nums.length;i++){
//            if(nums[i]==0)
//                count[0]++;
//            else if(nums[i]==1)
//                count[1]++;
//            else if(nums[i]==2)
//                count[2]++;
            if (nums[i]<0||nums[i]>2)
                return;
            count[nums[i]]++;
        }
        for (int i=0;i<nums.length;i++){
            if (i<count[0]){
                nums[i]=0;
            }else if (i>=count[0]&&i<count[1]+count[0]){
                nums[i]=1;
            }else if (i>=count[1]+count[0]&&i<count[2]+count[1]+count[0]){
                nums[i]=2;
            }
        }
    }
解法二:三指针法(三路快排)

利用三个指针,zero, i, two。分别表示的是:zero是当前最后一个0的索引位置,i 用来遍历数组,two是当前出现的第一个2的索引,即数组从[0,zero]存储的都是0,[zero+1, i -1] 存储的都是1,[i, two-1]为当前尚未遍历的元素,[two, 末尾] 存储的都是2.

一趟遍历,nums[i] 为0时,两种情况,一是i和zero相等时,直接zero+1,i+1,往下遍历,二是i和zero不相等时,与zero+1处的1做交换,zero++。但其实这两种情况都可以直接用两个语句来写:zero++; swap(numa,zero,i);.

nums[i]为1时候,什么都不用做,i直接往后面走,i+1;

nums[i]为2时,需要与two-1位置处的数字做交换,于是[two-1,nums.length-1]处都为2,因为交换过来的数字不确定是几,所以需要再次遍历访问i位置上的数字。在本例的代码中,因为for循环上i已经固定递增1,所以i需要减一。

当i遍历到two的前一个时,结束循环。

 public static void solve2(int[] nums){
        int zero = -1;         //[0,zero]中存储的是0
        int two = nums.length; //[two, nums.length-1]中存储的是2
        //第三个指针为i,用来遍历数组,从[zero+1,i-1]中存储的都是1
        for (int i=0;i<two;i++){
            if (nums[i]==0 ){   //遇到0的时候,与zero+1位置处的1做交换,此时[0,zero+1]存的都是0,[zero+2, i]都是1。
                zero++;
                swap(nums,zero,i);
            }else if (nums[i]==2){  //遇到2的时候,与two-1位置处的数字做交换,于是[two-1,nums.length-1]处都为2,因为交换过来的数字不确定是几,所以需要再次遍历访问i位置上的数字。
                two--;
                swap(nums,two,i);
                i--;
            }
        }
    }

    public static void swap(int[] source,int a, int b) {
        int temp = source[a];
        source[a]=source[b];
        source[b]=temp;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值