900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 搬砖小技巧|奇怪的知识又增加了

搬砖小技巧|奇怪的知识又增加了

时间:2022-12-24 03:52:50

相关推荐

搬砖小技巧|奇怪的知识又增加了

先上题目:

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

题目给出了例子,就是把形如{0,1,2,0,1}的数组排列成{0,0,1,1,2}。我一拍脑袋,这不简单,刷刷写完提交:

class Solution {public:void sortColors(vector<int>& nums) {return sort(nums.begin(), nums.end());}};

提交果然成功过了,但我一想,事情应该没有这么简单,我仔细一看,之间下面写了一行字:

必须在不使用库的sort函数的情况下解决这个问题。

好吧好吧,重新开始。

题目要求原地对它们进行排序,因此不能建立新数组。通过交换来变出要的数组太难做到,那就需要知道这个数组中每一种元素的个数,然后对原来的数组进行赋值。代码如下:

class Solution {public:void sortColors(vector<int>& nums) {int array[3] = {0,0,0};for(int i=0;i<nums.size();i++){array[nums[i]]++;}int index = 0;while(index<array[0]){nums[index] = 0;index++;}while(index<array[0]+array[1]){nums[index] = 1;index++;}while(index<array[0]+array[1]+array[2]){nums[index] = 2;index++;}}};

array[0], array[1], array[2]分别存储nums这个数组中0,1,2的个数,然后再按照顺序,对nums进行赋值。

代码是正确的,也能在规定时间内通过,但还是觉得太繁琐,看来一圈评论区,大佬是这么做的:

class Solution {public:void sortColors(vector<int>& nums) {int num0 = 0, num1 = 0, num2 = 0;for(int i = 0; i < nums.size(); i++) {if(nums[i] == 0) {nums[num2++] = 2;nums[num1++] = 1;nums[num0++] = 0;}else if(nums[i] == 1) {nums[num2++] = 2;nums[num1++] = 1;}else {nums[num2++] = 2;}cout << num0 << " " << num1 << " " << num2 << endl;}}};

由于我们最后得到的数组应该是由若干个0,若干个1,若干个2组成的数组,由于数组长度固定已知,其实我们只要知道从哪里开始0变成了1,又从哪里开始1变成了2。我之前的做法是先遍历一遍,知道0,1,2各自的数量,再遍历一遍根据得到的信息进行赋值,但是上述这段代码在一遍遍历中,完成了上述两件事情。

解释一下这段代码,以{0,2,1,0,1}为例:

我们用num0,num1,num2来记录最后一个0,1,2的位置,初始值均为0。

第一个数是0,那么比0大的1和2的位置都要往后顺移,由于这个位置是0,最后一个0也要往后移一个。[0]

第二个数是2,那么比2小的位置不变,最后一个2的位置要往后移一个。[0,2]

第三个数是1,那么比1大的2要往后瞬移一个,比1小的0不变,最后一个1的位置往后一个。[0,1,2]

第四个数是0,那么比0大的1和2的位置都要往后顺移,由于这个位置是0,最后一个0也要往后移一个。[0,0,1,2]

第五个数是1,那么比1大的2要往后瞬移一个,比1小的0不变,最后一个1的位置往后一个。[0,0,1,1,2]

由此,用了三个指针,完成了原地变换,大佬不愧是大佬。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。