一、发现问题
977. 有序数组的平方
给你一个按 非递减顺序 排序的整数数组
nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。示例 1:
输入: nums = [-4,-1,0,3,10] 输出: [0,1,9,16,100] 解释: 平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100]示例 2:
输入: nums = [-7,-3,2,3,11] 输出: [4,9,9,49,121]
直观思路:
先将nums各元素平方,再排序。
错误解答如下:
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortedSquares = function(nums) {
let arr=[];
for(i=0;i<nums.length;i++){
arr[i]=nums[i]*nums[i];
}
arr.sort();
return arr
};
测试用例:
输入:nums=[-4,-1,0,3,10]
输出:[0,1,100,16,9]
预期结果:[0,1,9,16,100]
发现100排在16的前面,sort()方法排序错乱。
二、问题原因
MDN文档中解释:
sort()方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的。
在比较数字大小时,会逐个比较,因此“100”会排在“16”前面。
三、解决办法
1.将比较函数作为参数传给sort()
function compare (val1,val2){
if(val1 < val2){
return -1
}else if(val1 > val2){
return 1
}else{
return 0;
}
}
var arr=[16,1,0,9,100]
console.log("排序前的数组",arr) //排序前的数组 [16, 1, 0, 9, 100]
arr.sort(compare);
console.log("排序后的数组",arr) //排序后的数组 [0, 1, 9, 16, 100]
2.将比较函数简化为箭头函数
var arr=[16,1,0,9,100]
console.log("排序前的数组",arr) //排序前的数组 [16, 1, 0, 9, 100]
arr.sort((val1,val2)=>val1>val2?1:val1<val2?-1:0);
console.log("排序后的数组",arr) //排序后的数组 [0, 1, 9, 16, 100]
3.若数组元素是数值,或是valueof()方法返回数值的对象(如Date对象),可进一步简化。
var arr=[16,1,0,9,100]
console.log("排序前的数组",arr) //排序前的数组 [16, 1, 0, 9, 100]
arr.sort((val1,val2)=>{return val1-val2;});
console.log("排序后的数组",arr) //排序后的数组 [0, 1, 9, 16, 100]