LeetCode Sort Colors 分块处理算法和优化counting sort算法

Sort Colors

 

Given an array with n objects colored red, white or blue, sort them 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.

click to show follow up.

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 an one-pass algorithm using only constant space?

科学思维: 这道题带点 QuikSort思想,

不过不如说是分窗口处理数据的思想,好像更贴切:O(∩_∩)O~

1 red窗口
2 white窗口
3 blue窗口
4 未处理窗口

算法一:下面是分三个指标,都指向各个颜色球的末位,这个算法的好处是可以很容易修改成分4个,5个颜色块的算法,当然如果颜色块继续增多,那么最好还是使用counting sort算法了,下面也给出了程序。

class Solution {
public:
	void sortColors(int A[], int n) 
	{
		int r = 0, r_w = 0, w_b = 0;
		for (int i = 0; i < n; i++)
		{
			switch (A[i])
			{
			case 0:
				{
					swap(A[i], A[r]);
					if (r_w != 0)
					{
						swap(A[i], A[r + r_w]);
					}
					if (w_b != 0)
					{
						swap(A[i], A[r + r_w + w_b]);
						//w_b++;这个颜色球并没有增加,所以不需要++
					}
					//注意:数值会变动,需要保存好,很容易忽略的。
					r++;
				}
				break;

			case 1:
				{
					swap(A[i], A[r + r_w]);
					if (w_b != 0)
					{
						swap(A[i], A[r + r_w + w_b]);
					}

					//注意:数值会变动,需要保存好,太容易忽略了。
					r_w++;
				}
				break;

			case 2:
				w_b++;
			}
		}
	}
};


算法二:利用三个分块的特性,分为前一块,后一块,中间一块,这样更加好处理,程序也简洁很多:

class Solution {
public:
	void sortColors(int A[], int n) 
	{
		int r = 0, w = 0, b = n-1;
		for (int w = 0; w <= b; )
		{
			switch (A[w])
			{
			case 0:
				swap(A[r++], A[w++]);
				break;

			case 1:
				w++;
				break;

			case 2:
				swap(A[w], A[b--]);
			}
		}
	}
};


算法三:Counting Sort算法,这是个通用的算法的了,非常常用。不过要使用额外空间O(n),想了很久,感觉好像不能不使用额外空间,不过可以优化一点,算法四给出程序。

void sortColors5(int A[], int n) 
	{
		int countArray[NUM_OF_COLORS+1] = {0};

		for (int i = 0; i < n; i++)
		{
			countArray[A[i]+1]++;
		}
		
		for (int i = 2; i <= NUM_OF_COLORS; i++)
		{
			countArray[i] += countArray[i-1];
		}

		vector<int> B(A, A+n);

		for (int i = 0; i < n; i++)
		{
			B[countArray[A[i]]++] = A[i];
		}

		for (int i = 0; i < n; i++)
		{
			A[i] = B[i];
		}
	}


算法四:优化counting sort,设关键字为m(本题的关键字为3)一般都比数列n长度小很多,如果使用额外空间O(m),那么就可以节省很多空间。如下面程序处理一下就可以做到了。

const static int NUM_OF_COLORS = 3;
	void sortColors4(int A[], int n) 
	{
		int countArray[NUM_OF_COLORS+1] = {0};

		for (int i = 0; i < n; i++)
		{
			countArray[A[i]+1]++;
		}
		
		for (int i = 2; i <= NUM_OF_COLORS; i++)
		{
			countArray[i] += countArray[i-1];
		}

		vector<int> fixedCount(countArray, countArray+NUM_OF_COLORS+1);

		int j = 0;
		for (int i = 0; i < n;)
		{
			if (A[i] != j)	swap(A[i], A[countArray[A[i]]++]);
			else 
			{
				countArray[j]++;
				i++;
			}
			while (i<n && j<=NUM_OF_COLORS && i == fixedCount[j+1])
			{
				j++;
				i = countArray[j];
			}
		}
	}


//2014-2-11 update
	void sortColors(int A[], int n) 
	{
		int red = 0, white = 0, blue = n-1;
		while (white<=blue)
		{
			if (A[white] == 0) swap(A[red++], A[white++]);
			else if (A[white] == 1) white++;
			else swap(A[white], A[blue--]);
		}
	}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值