力扣hot100 75题颜色分类 打卡

2021年11月25日

75. 颜色分类

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

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

思路分析:打眼一看,中等难度,也不知道题目要干啥,但是看了示例就清楚了,这不就是一个简单的排序题,所以上手就是调一个Arrays.sort的API,但是这样做就没什么意思了。本题一共有三个方法解决。

方法一:调API,是人都会(一行代码秒中等题的感觉,但是面试如果遇到,小心被面试官打死)

代码和提交结果如下:

class Solution {
    public void sortColors(int[] nums) {
        Arrays.sort(nums);
    }
}

 

 方法二:单指针算法

算法思路:

        我们可以使用一个指针指向数组的第一个位置,比如 int p = 0;先遍历一边数组,如果nums[i] == 0 ;就把nums[i] 与 nums[p] 的数互换位置,随后p++;因为要将数组按0,1,2的顺序排列,所以我们需要遍历扫描两遍数组,第一遍将所有的 0 换到数组的前面,然后 指针p 的位置刚好在最后一个 0 的后面,然后第二遍遍历数组,同样的办法将所有的 1 挪到 0 的后面。 图示如下图:      

代码和提交截图如下:

class Solution {
    public void sortColors(int[] nums) {
        int p = 0;
        for(int i = 0 ; i < nums.length ; i++){
            if(nums[i] == 0 ){
                int temp = nums[i];
                nums[i] = nums[p];
                nums[p] = temp;
                p++;
            }
        }
        for(int i = 0 ; i < nums.length ; i++){
            if(nums[i] == 1){
            int temp = nums[i];
            nums[i] = nums[p];
            nums[p] = temp;
            p++;
            }
        }
    }
}

  方法三:双指针算法

算法思路:

        上面一种算法我们使用了一个指针来进行移动和交换,所以导致每次只能换一个元素,所以我们可以考虑使用双指针,一次扫描便可以将数组完成排序。

        我们可以事先定义好两个指针,p0 和 p2 然后一个指向数组的头部,一个指向数组的尾部,然后扫描数组,如果nums[i] == 0 ;则将nums[i] 与 nums[p0] 位置交换, 如果nums[i] == 2 ;则将nums[i] 与 nums[p2] 位置交换,如果是 nums[i] == 2 交换的前提条件是 i < p2,不然就换回去了,所以,并且交换完之后nums[i]的位置还有可能是 2 ,但是 i 已经过去了,所以我们需要用while(i < p2 && nums[i] == 2){交换;p2--};代码和提交结果如下图:

class Solution {
    public void sortColors(int[] nums) {
        int p1 = 0;
        int p2 = nums.length - 1;
        for(int i = 0 ; i < nums.length ; i++){
            while(i < p2 && nums[i] == 2){
                    int temp = nums[i];
                    nums[i] = nums[p2];
                    nums[p2] = temp;
                    p2--;      
            }
            
            if(nums[i] == 0 ){
                int temp = nums[i];
                nums[i] = nums[p1];
                nums[p1] = temp;
                p1++;
            }   
        }  
    }
}

                                                                                                                                                                                  总结:还是尽量不要用API,并且方法三的时候一定要注意后面的特殊情况,不然会出错。 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值