方法一 splice:
通过数组的slice方法,碰到 0就在后面加一个0,最后截取原数组的长度,舍弃后面部分。
但这样做是违反了题目的要求,不要在超过该数组长度的位置写入元素。
var duplicateZeros = function(arr) {var len = arr.lengthfor(let i=0;i<len;i++){if(arr[i]===0){arr.splice(i,0,0)i++}}arr.splice(len)
};
消耗时间和内存情况:
方法二 ——方法一优化:
不直接操作arr,将arr的字符串形式赋值给str,对str按照要求进行修改,然后将str按位赋值给arr
这种方法也是算取巧
var duplicateZeros = function(arr) {var str = arr.join('').replaceAll('0','00')for(var i=0;i<arr.length;i++){arr[i]=str[i]}
};
消耗时间和内存情况:
方法三 两次遍历+双指针( 时间复杂度O(n) 空间复杂度O(1) )
用实例来说明:
arr =[0,1,7,6,0,2,0,7],arr里面虽然有3个0,但是前面两个0被复写完之后第三个0就被舍弃了,所以第一次遍历记录arr里有多少个0能被复写,并记录最后一个能被复写的0的位置
双指针left和right,right指向数组的末尾,left指向能被保留下来的最后一个元素,那么(left,right]之间的元素都是要被舍弃的。
如果left指向的是非0元素,那么就把left指向的元素移动到right处,left、right都往前移动一位
如果left指向的是0元素,则看这个0是不是能被复写的0,如果不是就按照非0元素处理,如果是则right以及right-1的位置都要被赋值为0
两次单层循环,没有使用其他数组或字符串,这应该才是最为理想的解法
var duplicateZeros = function(arr) {var right = arr.length-1,left=0,countfor(let i=0;i<arr.length;i++){if(arr[i]===0 && right-i>left){left++count=i} }left = right-leftwhile(left>=0){if(arr[left]===0 && left<=count){arr[right]=0right--arr[right]=0right--left--}else{arr[right]=arr[left]right--left--}}
};
消耗时间和内存情况: