leetcode75颜色分类

leetcode75 Sort Colors

Posted by BY on March 12, 2019

前言

新的一年,好好学习

正文

问题来源

本问题来自leetcode上的75题。

问题描述

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 (空间使用最少)

示例 1:

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

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

分析:

func sortColors(nums []int)  {
  count := make([]int,3)
  for i := 0; i < len(nums); i++ {
    count[nums[i]]++
  }
  for i := 0; i < count[0]; i++ {
    nums[i] = 0
  }
  count[1] += count[0]
  for i := count[0]; i < count[1]; i++ {
    nums[i] = 1
  }
  count[2] += count[1]
  for i := count[1]; i < count[2]; i++ {
    nums[i] = 2
  }
}

借助于快速排序的partition思想,以1为枢纽元对数组进行划分,使0在数组的左边,2在数组的右边,1在数组的中间。

class Solution {
public:
    void sortColors(int A[], int n) {
        //zeroEnd是放0那部分的尾部索引,twoEnd是放2那部分的首部索引
        //碰到0放到zeroEnd+1处,碰到2放到twoEnd-1处,碰到1指针后移
        int zeroEnd = -1, twoBegin = n, i = 0;
        while(i < twoBegin)
        {
            if(A[i] == 0 && i != ++zeroEnd)
                swap(A[zeroEnd], A[i]);
            else if(A[i] == 2 && i != --twoBegin)
                swap(A[twoBegin], A[i]);
            else
                i++;
        }
    }
};

总结:

勤思考。

结语

不管怎么样好好加油。