开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的28天,点击查看活动详情
题目:LeetCode
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
示例 1:
输入: nums = [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
示例 2:
输入: nums = [2,0,1]
输出: [0,1,2]
提示:
n == nums.length1 <= n <= 300nums[i]为0、1或2
解题思路
解法一:
分析该题由提示可知,这题元素只有0,1或者2, 就可以使用计数排序。 先遍历一遍,统计0, 1, 2的个数,然后先把0填充到结果数组,再填充1, 最后填充2, 就得到结果数组。
解法二: 使用双指针left,right,指针left左侧都是0,指针right右侧都是2,初始化left,right在数组的两端。
我们使用一个遍历变量i,遍历数组时nums[i]为0,则与左指针指向数字交换位置,然后左指针和i都向后移动,i左侧直到左指针都是1,当nums[i]为2时,则与右指针指向数字交换位置,然后右指针向左移动,i不变因为还要判断交换来的数字是什么,如果nums[i]为1,则不交换i向后移动,循环终止条件时i超过了右指针,此时后面已经是2,无需继续交换
代码实现
解法一:
public void sortColors(int[] nums) {
int[] countMap = {
0, 0, 0
};
Arrays.stream(nums).forEach(n -> countMap[n] ++);
int index = 0;
for (int k = 0; k < countMap.length; k++) {
for (int i = index; i < index + countMap[k]; i++) {
nums[i] = k;
}
index += countMap[k];
}
}
解法二:
public void sortColors(int[] nums) {
int left = 0, right = nums.length - 1;
int i = 0;
while (i <= right) {
if (nums[i] == 0) {
swap(nums, left, i);
left++;
i++;
} else if (nums[i] == 2) {
swap(nums, right, i);
right--;
} else {
i++;
}
}
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
运行结果
解法一:
解法二:
复杂度分析
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN) 一起分享知识, Keep Learning!