总体思路:
- 1,2,3分别代表不同颜色,只有3种颜色,所以只需用到3个指针i,j,k;
- i,j都执行0,k指向数组最后一位,其中j还表示当前所遍历的值,3个指针划分出4个区域:
- [0,i)放的是1
- [i,j)放的是2
- [j,k)放的是未划分的数
- [k,length-1]放的是3 - 然后就是从0开始遍历,判断当前值是哪个数,进行相应的指针移动或数字对调。
let str = '321322111231';
var sanseqi = function(ss){
//对于所传参数是字符串,要分离成数组,并对数组每个元素转为Number类型
let arr = ss.split('').map(Number);
//由于只是对3个不同的数归为一起
//所以设置3个指针i,j,k,其中
//[0,i)放的是1,[i,j)放的是2,[j,k)放的是未划分的数,[k,length-1]放的是3
let i =0;
let j = 0;
let k = arr.length - 1;
//因为k左边的数是未划分的,而j指的是当前正在遍历的数,所以只要j<=k即表明还有数未划分
while(j <= k){
//当前值为2
if(arr[j] === 2){
//因为[i,j)放的是2,即指针j左边的都是2,所以指针j要右移一位
j++;
console.log(arr);
//当前值为1
}else if(arr[j] === 1){
//因为[0,i)放的是1,即指针i左边的都是1,而当前值为1,
//所以指针i,j所指的值对调,即可保证1连续,所以i要右移一位,j也要右移一位,指向下一个数
[arr[i],arr[j]] = [arr[j],arr[i]];
i++;
j++;
console.log(arr);
//当前值为3
}else{
//因为[j,k)放的是未划分的数,即指针k左边的都是未划分的数,而当前值为3,
//所以指针j,k所指的值对调,即可保证3连续,所以k要左移一位,因为k右部的都是3
[arr[j], arr[k]] = [arr[k], arr[j]];
k--;
console.log(arr);
}
}
return arr;
}
console.log(sanseqi(str));
控制台打印的结果,执行的整个过程,如图:
最后说一下写代码中途出现的小问题:
1、let i,j = 0;
这样结果是不对的,出现了undefined,因为相当于i是undefined,
应该这样let i =0,j = 0;
2、表达式函数的遍历用let声明,后续报错Uncaught SyntaxError: Identifier ‘sanseqi’ has already been declared
应该用var来声明
3、对于其他的一些遍历,尽量用let声明,不然报错Uncaught SyntaxError: Identifier ‘str’ has already been declared
at :1:1