题目描述
原题链接
给定一个包含红色、白色和蓝色、共 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
 
进阶:
Javascript
排序
这里用快排来展示
/** @lc app=leetcode.cn id=75 lang=javascript** [75] 颜色分类*/// @lc code=startfunction swap(arr, a, b) {var temp = arr[a];arr[a] = arr[b];arr[b] = temp;}function quickSort(arr, begin, end) {if (begin >= end - 1) return;var left = begin;var right = end;do {do left++; while (left < right && arr[left] < arr[begin]);do right--; while (right > left && arr[right] > arr[begin]);if (left < right) swap(arr, left, right)} while (left < right);var swapPoint = left == right ? right - 1 : right;swap(arr, begin, swapPoint);quickSort(arr, begin, swapPoint);quickSort(arr, swapPoint + 1, end);}/*** @param {number[]} nums* @return {void} Do not return anything, modify nums in-place instead.*/var sortColors = function (nums) {quickSort(nums, 0, nums.length);};// @lc code=end
单指针
思路:两次扫描,第一次将所有的0交换道最前面
第二次将所有的1交换到前面
之后2就都在最后面了
/** @lc app=leetcode.cn id=75 lang=javascript** [75] 颜色分类*/// @lc code=start/*** @param {number[]} nums* @return {void} Do not return anything, modify nums in-place instead.*/var sortColors = function (nums) {const len = nums.length;let ptr = 0;for (let i = 0; i < len; i++) {if (nums[i] === 0) {[nums[i], nums[ptr]] = [nums[ptr], nums[i]]; // 交换ptr++;}}for (let i = ptr; i < len; i++) {if (nums[i] === 1) {[nums[i], nums[ptr]] = [nums[ptr], nums[i]];ptr++;}}};// @lc code=end
双指针
在单指针的基础上改进,用第一个指针表示0,第二个指针表示1,这样就能一次扫描完成
/** @lc app=leetcode.cn id=75 lang=javascript** [75] 颜色分类*/// @lc code=start/*** @param {number[]} nums* @return {void} Do not return anything, modify nums in-place instead.*/var sortColors = function (nums) {const len = nums.length;let ptr1 = 0;let ptr2 = 0;for (let i = 0; i < len; i++) {if (nums[i] === 0) {[nums[i], nums[ptr1]] = [nums[ptr1], nums[i]];if (ptr1 < ptr2) {[nums[i], nums[ptr2]] = [nums[ptr2], nums[i]];}ptr1++;ptr2++;} else if (nums[i] === 1) {[nums[i], nums[ptr2]] = [nums[ptr2], nums[i]];ptr2++;}}};// @lc code=end
Java
其他解法
Java
Javascript
双指针2
上面的双指针方法还可以用另一种思路来解决
第一个指针表示0
第二个指针从后面开始,表示2
这样0 移动到最前面,2移动到最后面,这样1就肯定是在中间的了
