方法一 个人方法:
以示例1为例:把[-4,-1,0,3,10] 中n<=0的元素拆分出来,把他们的平方从小到大放入arr数组,则arr=[0,1,16] ,那数组就还剩[3,10] 对于剩下的元素,看arr里面有没有比他们平方更小的元素先放入res数组,3的平方为9,0和1都小于9 ,所以先把0和1先加入res,再把3的平方9加入res,对于10也是如此。
有两种特殊情况需要考虑:
1、nums都是小于等于0的元素,那么arr的长度会等于nums的长度,直接返回arr
2、最大的元素在arr里那么循环结束时arr仍不为空,需要把arr里的元素都加入res
但是该方法嵌套了循环,时间复杂度超过了O(n)
var sortedSquares = function(nums) {var arr = [],res=[]for(var n of nums){if(n<=0){arr.unshift(n*n)}else{while(n*n >= arr[0]){res.push(arr.shift())}res.push(n*n)} if(arr.length===nums.length) return arr}while(arr.length){res.push(arr.shift())}return res
};
消耗时间和内存情况:
方法一优化版(O(n))两次遍历+双指针
还是拆分成两个数组minus保存n<=0的平方 ,plus保存n>0的平方,从minus和plus的开头开始比较,哪个更小就加入res并且向后移一位。当其中一个数组已经都加入res后,把另一个数组剩下的都加入res
var sortedSquares = function(nums) {var minus = [],plus=[],res=[]for(var n of nums){if(n<=0){minus.push(n*n)}else{plus.push(n*n)}}if(minus.length===0) return plusminus.reverse()if(minus.length===nums.length) return minusvar i=0,j=0while(true){if(minus[i]<=plus[j]){res.push(minus[i])i++}else{res.push(plus[j])j++}if(i===minus.length || j===plus.length) break}if(i===minus.length){for(j;j<plus.length;j++){res.push(plus[j])}}else{for(i;i<minus.length;i++){res.push(minus[i])}}return res
};
消耗时间和内存情况:
其他思路 (提供参考):
- 遍历所有数值,平方之后再排序,最差解
- 贪心,把所有负数扔在一个中间数组中,到正数的时候从中间数组拿出来所有的比正数小的先扔到结果数组中,然后再把当前值放在结果数组
- 双指针,从两端夹心对比,比较大的放到结果数组中,然后比较大的往中间进 1,小的不变继续对比