题目:给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
方法1. 辅助空间O(1), hash表统计每个数字个数,并重写数组
C++版:
void sortColors(vector<int>& nums) {
if (nums.empty()) return;
int count[3]{0}; // hash表,统计三个数字个数
for (auto num : nums) {
++count[num];
}
int start_index = 0; // 根据数字个数重写数组
for (int i = 0; i < 3; ++i) {
sortCore(nums, i, start_index, count);
}
}
void sortCore(vector<int> & nums, int num, int &start, int *count) { // 重写数组
while (count[num] > 0) {
nums[start++] = num;
--count[num];
}
}
方法2. 原地,三指针
Java版:
public void sortColors(int[] nums) {
// p0指向最右边的0的下一位,p2是最左端的2的前一位
int p0 = 0, p2 = nums.length - 1;
int i = 0; // 工作指针
while (i <= p2) {
if (nums[i] == 0) {
swap(nums, i++, p0++);//换完前进i 因为i之前不可能有2 不用担心换完新i的位置是2
} else if (nums[i] == 2) {//这里换完 新i的位置可能是0 所以i不能++
swap(nums, i, p2--);
} else { // nums[i] == 1 直接前进
i++;
}
}
}
void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}