题目:
难度:Middle
相关话题:排序
、数组
、双指针
给定一个包含红色、白色和蓝色,一共n 个元素的数组,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、1 和 2 分别表示红色、白色和蓝色。
注意: 不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
进阶:
思路:
直接来看一趟扫描法,要使用一趟扫描法,每个数字遍历的同时,就要将它放到正确的位置。
可以将数组划分为3块,用3个指针表示他们的边界,lo
表示0,hi
表示2,c
表示扫描的指针。
例如:001122
,这里lo
为2,表示索引0~1
一定都是0,hi
为3,表示索引4~5
一定为2.
因此每当nums[c]
对应的一个数字,便和那个数字对应的指针进行交换,并且指针需要前进一步。
(代码见最后)
这种方法稍加改变,同样也可以处理大量不同的重复值的排序,例如[1,1,2,2,3,3,4,4,4,4]
这种,比起一般的排序方法效率高出不少。
quick3way排序:
function quick3way(arr){
function sort(arr,lo,hi){
if(arr.length>1){
if(hi<=lo)return
let start=lo,cur=lo,end=hi;
let pivot=arr[lo]
while(cur<=end){
if(arr[cur]<pivot)swap(arr,cur++,start++)
else if(arr[cur]>pivot)swap(arr,cur,end--)
else cur++
}
sort(arr,lo,start-1)
sort(arr,cur,hi)
}
}
sort(arr,0,arr.length-1)
}
function swap(a, i, j) {
let t = a[i];
a[i] = a[j];
a[j] = t;
};
/**
* @来源: Javascript中文网 - 前端进阶资源教程 https://www.javascriptc.com/
* @介绍:一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var sortColors = function(nums) {
let l=0,r=nums.length-1
let pivot=1
for(let i=0;i<=r;i++){
if(nums[i]<pivot) swap(nums,i,l++)
else if(nums[i]>pivot) swap(nums,i--,r--)
}
function swap(arr,i,j){
let t=arr[i]
arr[i]=arr[j]
arr[j]=t
}
return nums
};