有接触过数据结构的同学应该知道排序有很多种类,我之前也出过一篇 排序大杂烩 的博客,其中包含了一部分排序的讲解,排序在我们学习编程的过程中有着至关重要的作用,不论是大部分新手刚开始接触的冒泡排序还是C++库中的sort函数,我们发现排序总是无处不在,所以接下来我将用我接触到的一道题 75. 颜色分类 来带大家了解一个新的排序:三路排序
思路解析
1. 关于题目我们知道 0 1 2 分别代表了三个不同的颜色,我们要做的就是将被打乱的数组排序成为 001122 这种形式的数组,并且不可以使用库函数 sort,也不可以开辟新的数组,在之前学习快速排序的过程中我们知道,快速排序是通过找出一个目标数字使得其左边均是比自己小的数字右边均是比自己大的数字,最终不断递归得到排列好的数组,但是快速排序有一个致命缺陷就是如果一个数组重复元素过多,那么就会不断退化,最终甚至效率还不如冒泡排序,所以我们有一个新的排序可以用来解决这个问题,那就是:三路排序
2. 三路排序就是首先 for 循环遍历数组将所有的 2 与最后的元素交换,然后使用一个变量 two_flag-- 作为下标不断缩小数组的长度,最终将2均放在数组的右侧,那么就可以使用 while 循环来操作,当然还不能忽略的一个限制条件就是 i < two_flag ,这样才不会越界
3. 对于 0 的操作就简单很多,直接从头开始遍历,创建一个 zero_flag 为下标,将所有0放 在数组的左边,使用 zero_flag ++ 缩小范围,最终 0 和 2 处理完成后 1 自然就在数组的 中间部分
class Solution {
public:
void sortColors(vector<int>& nums)
{
int zero_flag = 0;
int two_flag = nums.size() - 1;
for(int i = 0;i <= two_flag;i++)
{
while(nums[i] == 2 && i < two_flag)
{
swap(nums[i],nums[two_flag--]);
}
if(nums[i] == 0)
{
swap(nums[i],nums[zero_flag++]);
}
}
}
};
代码解析
1. 根据思路我们可以设计上述代码,首先使用 for 循环遍历数组,再使用 while 循环对数组 中的所有 2 进行右置操作,再使用 if 语句判断是否为 0 ,将 0 进行 左置操作,那么 1 就 自然排序在中间部分,最终返回原数组即可,不用开辟额外的空间也不用使用库函数