leetcode热题一百之颜色分类 排序和技巧
哈喽哈喽,我是你们的金樽清酒。我们知道leetcode里面的热题一百呀都是友友们很喜欢刷的题目。但是我刚刷到有一道题目中等的难度题目给我的感觉确实很简单,也正如我想的那样排序一下就能解决,但是题目说了哦,不能用内置的sort函数排序。
题目
给定一个包含红色、白色和蓝色、共 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
题目分析
一看题目的描述是不是很简单。就是将所给的数组,只有三种数字也就是三种颜色按从小到大排序就符合我们的题目了。乍一眼看过去不动脑子的想法就是排序--冒泡排序。
解法一 冒泡排序
var sortColors = function(nums) {
let len=nums.length;
for(let i=0;i<len;i++)
{
let temp;
for(let j=0;j<len;j++)
{
if(nums[i]<nums[j]){
temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
}
};
冒泡排序大家应该是会的吧。我觉得就算排序js有内置的函数,但是对于学习者来说工具虽然好用,但是我们还是得知道它得原理。得会一两种排序得方法比如冒泡排序,快速排序呀,选择排序呀。毕竟对排序的掌握是必不可少的。有些问题排一下序就解决了。
冒泡排序也有缺点,就是时间复杂度比较大。O(n^2)为了解决这个问题,那就需要技巧,有没有常数级别的解法呢?有,那就是用双指针的解法。
解法二 双指针
这是我在题解里面看到的,分享给大家。这道题目呀有一个别名叫做荷兰国旗问题算法。 思路 这道题可以使用荷兰国旗问题的思路来解决。 荷兰国旗问题是指:有一个数组,包含 3 种颜色的球(红、白、蓝),要求将这些球按照颜色顺序(红、白、蓝)排序。 思路: 我们可以设置 3 个指针,一个指向头部,一个指向尾部,还有一个指向当前遍历的元素。 我们从头部开始遍历数组,如果遇到 0(红色)就把它放到头部指针的位置,如果遇到 2(蓝色)就把它放到尾部指针的位置。 如果遇到 1(白色),就跳过它,继续遍历。
复杂度 时间复杂度: O(n), 因为双指针指针最多向右移动 n 次。
空间复杂度: O(1)
var sortColors = function(nums) {
let left = 0;
let right = nums.length - 1;
for (let i = 0; i <= right; i++) {
if (nums[i] === 0) {
swap(nums, i, left);
left++;
} else if (nums[i] === 2) {
swap(nums, i, right);
right--;
i--;
}
}
};
function swap(nums, i, j) {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
作者:黄昏再美也要天黑 链接:leetcode.cn/problems/so… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
怎么样,这个解法是不是更加的巧妙呢?所以说,这是一道中等难度的题。不在于解出来很难而在于如何优雅的解题。作为一个学者需要拓宽自己的思路,不断的改进自己的代码。好了,我的分享就到这里了。
假如您也和我一样,在准备春招。欢迎加我微信shunwuyu,这里有几十位一心去大厂的友友可以相互鼓励,分享信息,模拟面试,共读源码,齐刷算法,手撕面经。来吧,友友们!”