一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
每日刷题 2021.04.02
- leetcode原题链接:leetcode-cn.com/problems/so…
- 难度:中等
- 方法:双指针
题目
- 给定一个包含红色、白色和蓝色、共 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
解题思路
- 思路分析:需要会快速排序的思想。
- 在循环变量
i遍历的过程中,认为定义的循环不变的性质,决定了[初始化]、[遍历过程]和[循环终止]条件
本题思路
- 初始化:三个区间
[0,l)=> l以前的元素全部为0[l,r]=> 中间的全部为1(r,len - 1]=> r以后的全部为2- 分析:初始化的时候需要将这三个区间全部为0,即:
l = 0, r = len - 1,此时三个区间正好覆盖了整个数组
- 遍历过程:需要一个中间变量
i- 当
nums[i] == 0时,需要将其放到第一个区间中 - 当
nums[i] == 2时,需要将其放在第三个区间中 - 中间的
1不需要改变 - 注意:左边的交换后,需要将
i保留在当前位置
- 当
- 循环终止:当
i > r- Why? 因为:第三个区间
(r, len- 1]中,已经确定了其全部为排好的2,因此不需要再继续往后进行判断,无意义。
- Why? 因为:第三个区间
AC代码
var sortColors = function(nums) {
// 三个区间:左边一个区间 中间一个区间 右边一个区间
let len = nums.length;
let l = 0, r = len - 1,i = 0;
while(i <= r) {
if(nums[i] == 0){
let tempt = nums[l];
nums[l] = nums[i];
nums[i] = tempt;
l++;
}else if(nums[i] == 2){
// console.log(r,nums[r],i,nums[i])
let tt = nums[r];
nums[r] = nums[i];
nums[i] = tt;
// console.log('arr:', nums)
r--;
i--;
}
i++;
}
};
总结
- 循环不变量是写对代码、分析边界条件的基础