LintCode第143题-颜色分类 II

描述

给定一个有n个对象(包括k种不同的颜色,并按照1到k进行编号)的数组,将对象进行分类使相同颜色的对象相邻,并按照1,2,...k的顺序进行排序

  1. 不能使用代码库中的排序函数来解决这个问题
  2. k <= n

样例1

输入: 
[3,2,2,1,4] 
4
输出: 
[1,2,2,3,4]

样例2

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

挑战

可直接使用计数排序算法扫描两遍,但这样会花费O(k)的额外空间。你能否在O(logk)的额外空间的情况下完成

思路:首先第一种最简单的方法是快速排序 第二种是快速排序的改进版 增加了颜色的数量

代码如下:

第一种:

public class Solution {

    /**

     * @param colors: A list of integer

     * @param k: An integer

     * @return: nothing

     */

    public void sortColors2(int[] colors, int k) {//一定有重复的元素 考察排序算法特别是交换算法 常用的有冒泡和快速排序

        // write your code here

        //快速排序

        quickSort(colors,0,colors.length-1);

    }



 

    public  void quickSort(int[] a,int start,int end)

    {

        if (start >= end)

        {

            return;

        }

        int pivot=a[start+(end-start)/2];//枢轴值 枢轴值作为每轮目标值 进行排序

        int left=start, right=end;

        while(left<=right)

        {

            while(a[left]<pivot)//注意是while 而不是if  pivot = 数组里的某个元素 → 用 小于 或者大于 就够了 不能写<=或者>= 写了之后就会跳过去,不会停下,造成分区错误

            {

                left++;

            }

            while(a[right]>pivot)

            {

                right--;

            }

            if (left <= right)

            {

                swapElement(a, left, right);

                left++; right--;

            }

           

        }

         quickSort(a,start,right);

         quickSort(a,left,end);

    }

    public void swapElement(int a[],int left,int right)

    {

            int temp=a[left];

            a[left]=a[right];

             a[right]=temp;

    }

}

第二种:前面的一种pivot是数组中间的一个元素值

而这一种是通过颜色进行分割的

有了颜色区间,就能稳定地把元素按 ≤ColorMid和 >ColorMid来分,保证颜色范围被均匀拆开

代码如下:

public class Solution {

    /**

     * @param colors: A list of integer

     * @param k: An integer

     * @return: nothing

     */

    public void sortColors2(int[] colors, int k) {//一定有重复的元素 考察排序算法特别是交换算法 常用的有冒泡和快速排序

        // write your code here

        //快速排序

        quickSort(colors,0,colors.length-1,1,k);//注意这里的颜色区间为1...k 而不是0...k

    }



 

    public  void quickSort(int[] a,int start,int end,int colorStart,int colorEnd)

    {

        if (start >= end|| colorStart == colorEnd)

        {

            return;

        }

        int left=start, right=end;

        int ColorMid=colorStart+(colorEnd-colorStart)/2;

       

        while(left<=right)

        {

            while(left<=right&&a[left]<=ColorMid)//注意是while 而不是if pivot = 颜色区间的中点 → 必须明确规定“等于中点”的颜色归到哪边,所以用 <=>

            {

                left++;

            }

            while(left<=right&&a[right]>ColorMid)

            {

                right--;

            }

            if (left <= right)

            {

                swapElement(a, left, right);

                left++; right--;

            }

           

        }

         quickSort(a,start,right,colorStart,ColorMid);

         quickSort(a,left,end,ColorMid+1,colorEnd);// 改:ColorMid+1 按数组值的枢轴”换成了“按颜色区间中点划分

    }

    public void swapElement(int a[],int left,int right)

    {

            int temp=a[left];

            a[left]=a[right];

             a[right]=temp;

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值