LintCode 143. Sort Colors II

本文介绍了一种不使用标准库sort函数的颜色排序算法。该算法能在原地将包含K种不同颜色的对象数组按颜色升序排列。示例中给出了具体实现及测试代码。

This is a very interesting question! I like it!

#include <iostream>
#include <vector>
#include <climits>
using namespace std;

/*
  Given an array of n objects with K difference colors. sort them so that objects
  of the same color are adjacent, with the colors in the order 1, 2, ... k
  Note:
    You are not suppose to use the library's sort function for this problem.
  Exmaple:
  Given colors = [3, 2, 2, 1, 4], k = 4, you code should sort colors in-place to
  [1, 2, 2, 3, 4];
*/
void sortColorsII(vector<int>& colors, int k) {
  int start = 0;
  int end = colors.size() - 1;
  int count = 0;
  while(count < k) {
    int currMin = INT_MAX;
    int currMax = INT_MIN;
    for(int i = start; i <= end; ++i) {
      currMin = min(currMin, colors[i]);
      currMax = max(currMax, colors[i]);
    }
    int left = start;
    int right = end;
    int curr = left;
    while(curr <= right) {
      if(colors[curr] == currMin) {
        swap(colors[curr], colors[left]);
        curr++;
        left++;
      } else if(colors[curr] > currMin && colors[curr] < currMax) {
        curr++;
      } else {
        swap(colors[curr], colors[right]);
        right--;
      }
    }
    count += 2;
    start = left;
    end = right;
  }
}
int main(void) {
  vector<int> colors {3, 2, 2, 1, 4};
  sortColorsII(colors, 4);
  for(int i = 0; i < colors.size(); ++i) cout << colors[i] << endl;
}


### LintCode 143 排颜色 II 的 C++ 实现 #### 背景介绍 LintCode143 题名为“排颜色 II”,题目要求对数组中的三种颜色(0、1 和 2)进行原地排序,使得相同颜色的元素相邻,并按照红白蓝顺序排列。此题不允许使用库函数的排序功能[^2]。 以下是基于三指针法的高效解决方案: #### 解决方案分析 该算法的核心思想是通过三个指针分别追踪红色(0)、白色(1)和蓝色(2)的位置。遍历整个数组一次即可完成排序操作,时间复杂度为 O(n),空间复杂度为 O(1)[^2]。 #### C++ 实现代码 ```cpp #include <vector> using namespace std; class Solution { public: void sortColors2(vector<int>& nums) { int n = nums.size(); if (n == 0) return; int redIndex = 0; // 指向下一个应该放置红色的位置 int blueIndex = n - 1; // 指向下一个应该放置蓝色的位置 for (int i = 0; i <= blueIndex;) { // 使用循环控制索引移动 if (nums[i] == 0) { swap(nums[i], nums[redIndex]); ++redIndex; ++i; // 移动到下一位置 } else if (nums[i] == 2) { swap(nums[i], nums[blueIndex]); --blueIndex; // 不增加 i,因为交换后的值可能仍需处理 } else { ++i; // 当前值为 1,则跳过 } } } }; ``` 上述代码实现了高效的原地排序方法。`swap()` 函数用于交换两个元素的位置,从而调整它们在数组中的次序。 --- #### 关键点解析 1. **指针初始化**: `redIndex` 初始化为 0,表示第一个未被填充的颜色区域;`blueIndex` 初始化为最后一个元素下标,表示最后未被填充的颜色区域。 2. **边界条件**: 如果输入数组为空 (`n == 0`) 或仅有一个元素,则无需任何操作直接返回。 3. **优化细节**: 对于每次遇到颜色 2 的情况,由于其可能会覆盖尚未检查过的数据,因此需要保持当前索引不变以便重新评估新赋值的内容。 --- #### 时间与空间复杂度 - **时间复杂度**: 整体只需扫描一遍数组,故时间为线性级别 \(O(n)\)。 - **空间复杂度**: 所有操作均发生在原始数组上而无额外存储需求,因而空间消耗恒定为 \(O(1)\)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值