力扣最热一百题——颜色分类
目录
题目链接:75. 颜色分类 - 力扣(LeetCode)
题目描述
示例
提示:
解法一:不要脸用sort
Java写法:
运行时间
解法二:O1指针
Java写法:
重点
运行时间
C++写法:
运行时间
时间复杂度和空间复杂度
总结
题目链接:75. 颜色分类 - 力扣(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.length
1 <= n <= 300
nums[i]
为0
、1
或2
进阶:
- 你能想出一个仅使用常数空间的一趟扫描算法吗?
解法一:不要脸用sort
既然题目都说了不让用sort,那么我这种一生逆骨的选手是必须要用一下的嘿嘿。
Java写法:
class Solution {
public void sortColors(int[] nums) {
Arrays.sort(nums);
}
}
运行时间
真爽啊哈哈哈哈哈哈哈哈哈
解法二:O1指针
Java写法:
class Solution {
public void sortColors(int[] nums) {
// p0用于交换0
int p0 = 0;
// p1用于交换1
int p1 = 0;
// 进入交换逻辑
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 1) {
// 遇到1
int temp = nums[i];
nums[i] = nums[p1];
nums[p1] = temp;
p1++;
} else if (nums[i] == 0) {
// 遇到0
int temp = nums[i];
nums[i] = nums[p0];
nums[p0] = temp;
// 确保在遇到 0 时,p0 和 p1 之间的元素都是 1
if (p0 < p1) {
temp = nums[i];
nums[i] = nums[p1];
nums[p1] = temp;
}
p0++;
p1++;
}
}
}
}
重点
-
变量定义:
p0
:用于指向0
的位置。p1
:用于指向1
的位置。
-
循环遍历数组:
- 当遍历到元素
1
时,代码会将其与p1
位置的元素交换,然后p1
向右移动一位。 - 当遍历到元素
0
时,代码会将其与p0
位置的元素交换,然后p0
向右移动一位,p1
也向右移动。
- 当遍历到元素
-
if (p0 < p1)
逻辑:- 这一条件判断是为了确保在遇到
0
时,p0
和p1
之间的元素都是1
。 - 这样做的目的是在
0
被移动到前面时,同时也要把1
移动到p1
的位置,确保1
被正确放在0
的右边。
- 这一条件判断是为了确保在遇到
-
避免重复处理:
- 只有在
p0
小于p1
时,才进行这次交换,因为这表示p0
和p1
之间有1
,需要将当前的0
和1
进行交换,以保持排序。
- 只有在
运行时间
C++写法:
class Solution {
public:
void sortColors(vector<int>& nums) {
// p0 用于交换 0
int p0 = 0;
// p1 用于交换 1
int p1 = 0;
// 进入交换逻辑
for (int i = 0; i < nums.size(); i++) {
if (nums[i] == 1) {
// 遇到 1
swap(nums[i], nums[p1]);
p1++;
} else if (nums[i] == 0) {
// 遇到 0
swap(nums[i], nums[p0]);
// 确保在遇到 0 时,p0 和 p1 之间的元素都是 1
if (p0 < p1) {
swap(nums[i], nums[p1]);
}
p0++;
p1++;
}
}
}
};
运行时间
时间复杂度和空间复杂度
总结
Ez就完事啦~~~~~