leetcode-75-颜色分类(sort colors)-java

题目及测试

package pid075;
/*颜色分类

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

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

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

示例:

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

进阶:

    一个直观的解决方案是使用计数排序的两趟扫描算法。
    首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
    你能想出一个仅使用常数空间的一趟扫描算法吗?




*/
public class main {
	
	public static void main(String[] args) {
		int[] testTable = {2,0,2,1,1,0};
		test(testTable);
		
	}
		 
	private static void test(int[] ito) {
		Solution solution = new Solution();
		int rtn;
		long begin = System.currentTimeMillis();
		System.out.println("ito=");
		for(int i=0;i<ito.length;i++){			
			System.out.print(ito[i]+" ");						
		}
		System.out.println();
		solution.sortColors(ito);//执行程序
		long end = System.currentTimeMillis();
		System.out.println("rtn=");
		for(int i=0;i<ito.length;i++){			
			System.out.print(ito[i]+" ");						
		}
		System.out.println();
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,1ms,很快)

用的是题目中的一次扫描个数,二次重写数组的方法,没想出来一次扫描排序

package pid075;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Solution {
	
public void sortColors(int[] nums) {
    int length=nums.length;
    if(length==0||length==1){
    	return;
    }
    int[] num=new int[3];
    for(int i=0;i<length;i++){
    	int now=nums[i];
    	num[now]++;
    }
    for(int i=0;i<num[0];i++){
    	nums[i]=0;
    }
    for(int i=num[0];i<num[0]+num[1];i++){
    	nums[i]=1;
    }
    for(int i=num[0]+num[1];i<length;i++){
    	nums[i]=2;
    }
	
	return;
    }
}

解法2(成功,0ms,极快)

如果只能扫一遍,很容易想到的就是左边存放0,右边存放2. 中间放1。

设置两个index,index0记录下一个0的位置,index0左边为0,index2记录下一个2的位置,index2右边为2.

然后使用i从头到尾扫一遍,直到与index2相遇。

i遇到0就换到左边去,遇到2就换到右边去,遇到1就跳过。

需要注意的是:由于index0记录第一个1的位置,因此A[index0]与A[i]交换后,A[index0]为0,A[i]为1,因此i++;

而index2记录第一个非2的位置,可能为0或1,因此A[index2]与A[i]交换后,A[index2]为2,A[i]为0或1,i不能前进,要后续判断。

由此该数组分为4段:[0,index0)-->0; [index0,i)-->1; [i,index2]-->乱序; (index2,n-1]-->2

0  0  0  1  1  1  2  1  0  2  1  2  2  2

           ^         ^             ^

          index0  i            index2

    public void sortColors(int[] nums) {
    	if(nums.length==0||nums.length==1){
    		return;
    	}
        int index0=0;
        int index2=nums.length-1;
        for(int i=0;i<=index2;){
        	int now=nums[i];
        	if(now==0){
        		swap(nums, i, index0);
        		index0++;
        		i++;
        		continue;
        	}
        	if(now==2){
        		swap(nums, i, index2);
        		index2--;
        		continue;
        	}
        	if(now==1){
        		i++;
        		continue;
        	}
        }
    	
    	return;
    }	
	
	public void swap(int[] nums,int i,int j){
		int temp=nums[i];
		nums[i]=nums[j];
		nums[j]=temp;
	}

 

 

 

 

 

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值