谈一谈那些非正常排序题目

本文探讨了LeetCode中的一些非典型排序题目,包括75.颜色分类(荷兰国旗问题)、280.摆动排序、324.摆动排序 II和376.摆动序列。通过不同策略如两遍扫描、一次扫描、排序+交换、快速选择和3way-partition等,解析了解题思路和优化方法,旨在揭示排序算法的多样性和复杂性。
摘要由CSDN通过智能技术生成

写在前面

在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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客不撩妹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值