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.
问题描述: 给定一个数组,数组里的每个元素代表一种颜色,红色用0表色,白色用1表示,蓝色用2表示,对数组进行一定的操作,使得数组中的0,1和2按顺序排列,即前面的都是0,然后到1,最后到2。
解题思路: 看到这个题目,一开始很容易就想到对数组中的元素进行排序不就行咯?确实进行排序后是可以得到正确的结果,但是是否有这样的必要呢?毕竟排序的复杂度不低。而且题目中已经给出了注意事项,不要用排序的方法来解决这个问题。所以,可不可以通过元素之间的交换来解决得到结果。 先从一个简单的问题开始,从左往右遍历数组nums,遍历到第i元素,假如数组的前i个元素已经符合了题目的要求,那么我们应该怎样将第i个元素插入到前面的i个元素中,使得数组前i+1个元素满足题目的要求,如下图。
可以看到,当nums[i]为0的时候,经过2个步骤的交换,就可以让前i个元素满足题目的要求,当nums[i]为1的时候,只需要经过1个步骤的交换,就可以满足要求,而且很容易想到,当nums[i]为2的时候,不需要任何的操作。这样,当我们每遍历完一个元素,都可以保证遍历过的元素都是符合题目要求的,直到遍历到最后一个元素。在使用这种方法的时候,关键点就是要记录当遍历到第i个元素的时候,前i个元素中第一个1的位置,和第一个2的位置,假如分别命名为start1和start2。
当遍历到一个值为0的元素之后,经过2步交换后,需要把start1和start2都往后移动一位;当遍历到一个值为1的元素之后,经过1步交换后,需要把start2往后移动一位;当遍历到一个值为2的元素之后,不需要交换,也不需要改变start1和start2;而因为这些start1和start2都是初始化为0,如果给出的数组中不存在1,那么start1和start2是永远都是想等的,那么就存在了一个问题,那就是遇到上图中nums[i]为1这种情况的时候,会发现经过2次交换后,数组的元素顺序是没有变化的,所以如果遇到nums[i]为1的情况,只需要执行一次的交换,因为start1和start2是一样的,所以不管是执行了第一个交换还是第二个交换,都是可行的。
代码:
#include <iostream>#include <vector>using namespace std;void swap(vector<int>& nums, int x, int y) { int temp = nums[y]; nums[y] = nums[x]; nums[x] = temp;}void PrintNums(vector<int>& nums) { cout << "[ "; vector<int>::iterator it = nums.begin(); for (; it != nums.end(); it++) { cout << *it << " "; } cout << "]" << endl;}class Solution {public: void sortColors(vector<int>& nums) { int start0 = 0, start1 = 0, start2 = 0; int i = 0; while (i < nums.size()) { switch (nums[i]) { case 0: if (i >= start1) { swap(nums, i, start1); if (start1 != start2) swap(nums, i, start2); start1++; start2++; } break; case 1: if (i >= start2) { swap(nums, i, start2); start2++; } break; } i++; } }};int main(int argc, char** argv) { int array[] = {0, 1, 2, 1, 1}; int count = sizeof(array) / sizeof(int); vector<int> nums(array, array + count); Solution sln; sln.sortColors(nums); PrintNums(nums); return 0;}新闻热点
疑难解答