75. Sort Colors

75. Sort Colors

1. 题目

Given an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white and blue.
Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.
Note: You are not suppose to use the library’s sort function for this problem.
Example:
Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
Follow up:
A rather straight forward solution is a two-pass algorithm using counting sort.
First, iterate the array counting number of 0’s, 1’s, and 2’s, then overwrite array with total number of 0’s, then 1’s and followed by 2’s.
Could you come up with a one-pass algorithm using only constant space?

2. 题目分析
颜色排序,其实就是0,1,2三个值进行排序,空间复杂度为常量,快排符合,但最好的适合普遍情况的排序算法的时间复杂度为O(nlogn),那有没有更快的呢,即O(n)?就像奇偶数排序(奇数放前面,偶数放后面)的问题,可以直接使用两个指针解决方案。

3. 解题思路
两种解决思路:

  • 计数排序算法,因为只要对三个值排序,所以可以统计每个数字出现的次数,然后依次赋值到数组中。
  • 同样可以用两个指针实现调换位置,即left指向在左边0移动的位置,即left记录第一个非0的位置,left左边为0;right指向在右边2移动的位置,即right记录第一个非2的位置,right右边为2;而1位于中间,可以不变。
    然后使用i从头到尾扫一遍,直到与right相遇。i遇到0就换到left左边去,遇到2就换到right右边去,遇到1就跳过。
    需要注意的是:当遇到2就换到right右边去,换回来的可能是0(或者1),i不能立刻前进。因为如果换回来的是0,left在i前面,那么i前面会有1,要继续交换;

4. 代码实现(java)

package com.algorithm.leetcode.sort;

/**
 * Created by 凌 on 2019/1/17.
 * 描述:75. Sort Colors
 */
public class SortColors {
    public static void main(String[] args) {
        int[] nums = {2,0,2,1,1,0};
//        sortColors(nums);
        sortColors_1(nums);
        for (int i = 0; i < nums.length; i++) {
            System.out.printf(nums[i] + "\t");
        }
    }

    /**
     * 计数排序:时间复杂度O(n)空间复杂度O(1)
     * @param nums
     */
    public static void sortColors(int[] nums) {
        if(nums == null || nums.length == 0){
            return;
        }
        int[] sort = new int[3];
        for (int i = 0; i < nums.length; i++) {
            sort[nums[i]]++;
        }
        int count = 0;
        for (int i = 0; i < sort[0]; i++) {
            nums[count++] = 0;
        }
        for (int i = 0; i < sort[1]; i++) {
            nums[count++] = 1;
        }
        for (int i = 0; i < sort[2]; i++) {
            nums[count++] = 2;
        }
    }
    /**
     * 时间复杂度O(n)空间复杂度O(1)
     * @param nums
     */
    public static void sortColors_1(int[] nums) {
        if(nums == null || nums.length == 0){
            return;
        }
        int left = 0;
        int right = nums.length - 1;
        int count = 0;
        while (count <= right){
            if (nums[count] == 2){
                int temp= nums[count];
                nums[count]= nums[right];
                nums[right] = temp;

                right--;
            }else if (nums[count] == 0){
                int temp= nums[count];
                nums[count]= nums[left];
                nums[left] = temp;
                left++;
                count++;
            }else if (nums[count] == 1){
                count++;
            }
        }
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值