系列文章
- [ CodeWar ] - 001:过滤重复字符
- [ CodeWar ] - 002:最大和最小值
- [ CodeWar ] - 003:判断质数
- [ CodeWar ] - 004:处理数组元素
- [ CodeWar ] - 005:用户分组
- [ CodeWar ] - 006:数组比对
- [ CodeWar ] - 007:找不同
- [ CodeWar ] - 008:分割字符串
- [ CodeWar ] - 009:哈希标签生成器
- [ CodeWar ] - 010:大数相加
- [ CodeWar ] - 011:最短路径
- [ CodeWar ] - 012:rgb 转 hex
- [ CodeWar ] - 013:解析化学式
- [ CodeWar ] - 014:解析公有质因
- [ CodeWar ] - 015:字符串解析统计
- [ CodeWar ] - 016:数组排序
题目

这题目乍一看简单的不行,然后往右边一瞟:

这么多限制条件得吗???
如果仅仅是面向 codewars 编程,还有如下的骚操作:

当然,这里还是顺着题目的意思,满足它一下吧。
解析
首先我们来看看限制:
- 不能用临时数组
0的顺序也不能变- 不能用任何数组或对象的原生方法,比如
sort(), push(), map()等等
那么这里首先想到的应该是冒泡(因为简单),这里需要做的,无非就是把前面的 0 通过冒泡排到最后,然后重新循环,遇到 0 又扔到最后去。
但如果按照上面的思路,将会有下面的坑:
连续的多个
0将导致排序失效
input = [7, 2, 3, 0, 4, 6, 0, 0, 13, 0, 78, 0, 0, 19, 14]
output = [7, 2, 3, 4, 6, 0, 13, 78, 0, 19, 14, 0, 0, 0, 0]
至于为什么会这样,通过调试器看一下就明白了。
这里有两种思路:
- 通过一个变量记录
0的个数,这个数每+1,则循环下标-1 - 将数组倒过来遍历
显然第二种方法要简单很多,那么我们来看看实现代码:
function removeZeros(arr) {
let len = arr.length,
n,
t
for (let i = len - 1; i > -1; i--) {
n = arr[i]
if (parseFloat(n) === 0) {
len--
for (let j = i + 1; j <= len; j++) {
t = arr[j - 1]
arr[j - 1] = arr[j]
arr[j] = t
}
}
}
return arr
}
优化
上述代码有什么地方可以优化呢?
- 首先最后两位不管是不是 0,都一定是不用遍历的,所以
i的初始值可以设置为len - 2 - 利用
js ,运算符 - 利用数组完成变量交换
那么最终代码如下:
function removeZeros(arr) {
for (let len = arr.length, i = len - 2; i > -1; --i)
if ('' + arr[i] === '0') for (let j = (--len, i + 1); j <= len; j++) arr[j - 1] = [arr[j], (arr[j] = arr[j - 1])][0]
return arr
}