【C语言】75. 颜色分类(三路快排)


题目

链接: link
在这里插入图片描述

思路(仅一趟循环判断完成)

本题要求对原地对数组中包含红色(0)、白色(1)和蓝色(2)三种颜色进行排序,不使用库函数。
解题步骤

  1. 分别设置两个索引 zerotwo,保证下标 0 到 zero 对应的数组元素都为 0,下标 two 到 numsSize - 1对应的数组元素都是 2;
  2. 设置索引 i 用于遍历整个数组,遍历到 i 个元素的时候,保证下标 zero + 1 到 i - 1对应的数组元素都是 1;
  3. 当索引 i 遍历到元素 1 时,直接将元素 1 纳入到属于 1 的部分,然后继续遍历;
  4. 如果遍历到元素 2 时,将two 前面的索引 two - 1 对应的元素与遍历到的元素 2 交换,将元素 2 纳入到属于 2 的部分;
  5. 如果遍历到元素 0时,交换下标为 zero 后面的索引 zero + 1 对应的元素与遍历到的元素 0,将元素 0 纳入到属于 0 的部分。

初始的数组以及索引位置

  1. nums[0…zero] == 0 保证下标为 0 到 zero 对应的元素都为 0
  2. nums[zero+1…i-1] == 1 保证下标为 zero + 1 到 i - 1 对应的元素都为 1
  3. nums[two…n-1] == 2 保证下标为 two 到 n - 1 对应的元素都为 2

初始化zero为-1,two为numsSize是防止数组中不存在0或2
在这里插入图片描述

由于当遇到元素2时,需要把 nums[i] 与 nums[two-1] 交换,之后就需要再次判断 nums[i] ,所以再设置for循环时,不要放入i++条件,而是通过遇到元素0或元素1时再往后判断
假设第一个遇到的是 元素1

i加一,判断下一个元素
在这里插入图片描述

假设接着遇到的是 元素0
需要交换数组中下标为 zero+1 和下标为 i 的元素,然后在进行 i++ 判断下一个元素,而 zero 作为元素0的末尾坐标,往后加一,即zero++
在这里插入图片描述

假设接着遇到的是 元素2
需要交换数组中下标为 numsSize-1 和下标为 i 的元素,此时因为把 numsSize-1 的元素提到了前面,所以需要再次判断 i 下标的元素,而 two 作为元素2的起始坐标,往前加一,即 two–
在这里插入图片描述

代码呈现

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

void sortColors(int* nums, int numsSize){
    int zero = -1;            
    int two = numsSize;        
    for (int i = 0; i < two;) {
        if (nums[i] == 1) {
            i++;
        } else if (nums[i] == 2) {
            swap(&nums[i], &nums[--two]);
        } else if (nums[i] == 0) {
            swap(&nums[++zero], &nums[i++]);
        }
    }
}

思路(冒泡)

由于只需要将数组按0.1.2的顺序排列出来,所以只需要用两趟冒泡排序将数组给排序就行,但是这种方法的适用性有些低,在元素不是升序而是乱序的时候就无法使用,所以建议使用第一种思路,但是这里还是把冒泡排序的代码给表示出来。

void swap(int* a, int* b) {
    int* tmp = *a;
    *a = *b;
    *b = tmp;
}
void sortColors(int* nums, int numsSize) { 
    for (int i = 0; i < numsSize; i++) {
        for (int j = i + 1; j < numsSize; j++) {
            if (nums[i] > nums[j])
                swap(&nums[i], &nums[j]);
        }
    }
}
  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值