leetcode(75)- 颜色分类

75.颜色分类
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

思路

这题目乍一看还没看懂,我还以为就是一个升序排序问题,看了下应该是一个分类的问题,将相同类别合并到一起,感觉跟最近学的机器学习挺像的将数字啥的聚类。这里还是比较简单,就三种类别,然后又是数组的题目,一般就是用双指针或者多指针来解决问题,这里也是用双指针的解法。
这里我们只要界定了0和2的边界,那么1也就自然排序好了。
1、将0的边界指向数组第一个元素
2、将2的边界指向数组的最后一个元素
3、从头到尾开始遍历数组

  • 如果当前值是0,就和0边界的元素交换
  • 如果当前值是2,就和2边界的元素交换
  • 如果当前值是1,就检索下一个元素
  • 如果处理完后当前检索位置大于等于p2的位置那么就退出程序

代码实现

class Solution {
    public void sortColors(int[] nums) {
    	int p0 = 0, p2 = nums.length - 1;
    	for(int i = 0; i < nums.length; i++)
    	{	
    		if(nums[i] == 0)
    		{
    			swap(nums,i,p0);
    			p0++;
    		}else if(nums[i] == 2)
    		{
    			swap(nums,i--,p2);
    			p2--;
    		}
    		if(i >= p2)
    			break;
    	}
    }
    //交换数组的第a个数和第b个数
    private void swap(int[] nums,int a,int b)
    {
        if(a == b || nums[a] == nums[b])
    		return;
    	nums[a] = nums[a] + nums[b];
    	nums[b] = nums[a] - nums[b];
    	nums[a] = nums[a] - nums[b];
    	
    }
}

这里有点点细节需要考虑:
假如初始化是:{1,2,0},p0 = 0,p2 = 2, i = 0
第一次交换后是:{1,2,0},p0 = 0, p2 = 2, i = 1,
第二次交换后是:{1,0,2},p0 = 0, p2 = 1, i = 2,这时候 i >= p2理应退出遍历,但是我们发现0其实我们是没有处理过的,它是被交换到数组中的位置1处的,所以这个时候我们不能将i++,但是我写的for循环里面写了++,所以在向后交换的时候加上了i–来抵消i++,如下情况:

    		if(nums[i] == 0)
    		{
    			swap(nums,i,p0);//向前交换不用考虑
    			p0++;
    		}else if(nums[i] == 2)
    		{
    			swap(nums,i--,p2);//向后交换,再处理一边交换过来的数
    			p2--;
    		}

在这里插入图片描述

发布了81 篇原创文章 · 获赞 21 · 访问量 8810

猜你喜欢

转载自blog.csdn.net/qq_37668436/article/details/105177980
今日推荐