「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。
题目
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
示例1
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例2
输入:nums = [2,0,1]
输出:[0,1,2]
思路
猛地一看,这道题好像就是个简单的排序问题,题目唯一要求的就是原地排序,就是要在传进来的数组上做变更,而不能以返回一个新变量的方式。
对数组进行排序,很容易就会想到之前常说的冒泡排序法:
冒泡排序代码
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var sortColors = function (nums) {
const n = nums.length;
if(n < 2) return;
let temp;
for(let i = 0; i < n; i++) {
for(let j = i + 1; j < n; j++) {
// 数值大的往后放
if(nums[i] > nums[j]) {
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
};
冒泡排序算法的时间复杂度为 O(n ^ 2)
,是比较稳定的一种算法,但是效率不是很高
使用 Array.sort
对于数组的排序,Array
的原型上也提供了一种方法 sort
,该方法接受一个比较函数 fn
,若 fn
的返回值小于0,则 a
会放在 b
之前,大于0则反之,等于0不做变换。同时 sort
也是对数组进行原地排序,不会进行复制。
nums.sort((a, b) => a - b);
双指针+遍历
上面的冒泡和 sort
排序都是通用的算法,但是对于本题,数组中只存在 0,1,2
三种数字;我么只需要把 0
排到最前面,把 2
排到最后面,完成之后,原数组就是按照题目要求排序的了
具体实现:
-
定义
left
为头部0
的右边界,right
为尾部2
的左边界,index
为当前遍历索引 -
上述初始值为:
left = index = 0, right = nums.length - 1
; -
当
index <= right
时,进入循环- 如果当前
nums[index] === 0
, 将nums[left] 和 nums[index] 交互,并将 left++, index++
- 如果当前
nums[index] === 1
, 将index++
, 无需进行交换操作 - 如果当前
nums[index] === 2
, 将nums[right] 和 nums[index] 交互,并将 right--
,这里不能将index++
,因为nums[right]
也可能为2
- 如果当前
-
结束循环后,
nums
排序即完成
完整代码实现
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var sortColors = function (nums) {
let left = 0, index = 0, right = nums.length - 1;
// 定义交换方法,解构赋值
const swap = (i, j) => {
[nums[i], nums[j]] = [nums[j], nums[i]];
}
while(index <= right) {
if(nums[index] === 0) {
// 把 0 交换到前面
swap(index, left);
index++;
left++;
} else if(nums[index] == 1) {
// 不用交换
index++;
} else {
// 把 2 交换到后面
// 因为可能交换过来的 nums[right] 也可能是 2,不能将index++
swap(index, right);
right--;
}
}
};
上述代码的时间复杂度最大为 O(n)
,最多进行一次完成的循环,即可完成排序
小结
有一些思路,例如冒泡排序,是适用于较多数情况下都可进行的,但他的性能、效率一般都不是很好。针对于本道题,分析 nums
中只有三种元素,可以针对的进行一些操作,使得解法的效率变高。
# LeetCode 👉 HOT 100 👉 颜色分类 - 中等题 ✅
合集:LeetCode 👉 HOT 100,有空就会更新,大家多多支持,点个赞👍
如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄