写在前面
在leetcode上面刷到几道很有意思的排序题,和传统的排序题不一样,很有意思。
75. 颜色分类
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
直接排序的方法我们就先不考虑了,因为最快也只能O(n*log(n))。
两遍扫描
最容易想到的解法,就是一次遍历统计出0,1,2的个数,然后再顺序放进数组。
这样需要遍历两次,思路很清晰,代码这里就略去了。
一遍扫描(荷兰国旗问题)
因为只有012三种数字,所以最后的结果肯定是这样的:
00000……00000011111……11111111222222……2222222
我们其实只要找到两个交界点就行了。
所以我们假设出两个指针,p1,p2,
初始化:p1 = 0, p2 = nums.size()-1。
然后再维护一个curr指针,这个指针从头扫到尾。
算法:
当curr<=p2:
- nums[curr]==0: nums[curr]和nums[p1]交换,然后p1和curr都往后移。
- nums[curr]==1: curr+1
- nums[curr]==2: nums[curr]和nums[p2]交换,p2-1.
代码:
class Solution {
public:
void sortColors(vector<int>& nums) {
if(nums.empty()) return;
int n = nums.size();
int p1(0),p2(n-1),curr(0);
while(curr<=p2){
if(nums[curr]==0){
swap(nums[p1],nums[curr]);
++p1;
++curr;
}
else if(nums[curr]==2){
swap(nums[p2],nums[curr]);
--p2;
}
else{
++curr;
}
}
return;
}
};
280. 摆动排序
给你一个无序的数组 nums, 将该数字 原地 重排后使得 nums[0] <= nums[1] >= nums[2] <= nums[3]…。
示例:
输入: nums = [3,5,2,1,6,4]
输出: 一个可能的解答是 [3,5,1,6,2,4]
排序+交换
最容易想到的就是先排序,然后从第二个开始,每两个交换一下,就可以满足要求了。
代码:
class Solution {
public:
void wiggleSort(vector<int>& nums) {
if(nums.empty()) return;
sort(nums.begin(),nums.end());
int p=1;
while(p<nums.