题目如下
给你一个长度为
n
的整数数组nums
,请你返回nums
中最 接近0
的数字。如果有多个答案,请你返回它们中的 最大值 。
1 <= n <= 1000
-10^5 <= nums[i] <= 10^5
这道题是一道简单题,写起来也十分的轻松,用暴力就能写。
暴力解法
var findClosestNumber = function(nums) {
for(let i=0;i<=100000;i++){
if(nums.includes(i)){
return i;
}else if(nums.includes(-i)){
return -i;
}
}
};
由于规定了数组里值最大只能为100000,所以我们可以写一个for循环,从0到100000,搜索i或-i是否在数组中.如果在数组中的话就返回这个数,由于是从小到大的,而且if语句是先判断正再判断负的,所以能满足题目要求。运行结果如下。
不难看见,虽然能通过,但是由于暴力解法,时间消耗很不理想。因此,我们需要换一种更好的算法。
求绝对值后排序
由于数组中的值有正有负,所以我们可以先将负数转化为正数,这样每个数的值就变成了他距离0的距离,排序后第一个值就是离0最小的值的距离。但是我们要注意,要保留原数组不变,因为最后要判断这个值是正是负。
var findClosestNumber = function(nums) {
let temp = [...nums];
for(let i=0;i<nums.length;i++){
if(nums[i]<0){
nums[i] = -nums[i];
}
}
let min = Math.min(...nums);
if(temp.includes(min)){
return min;
}else{
return -min;
}
};
时间比上一个算法快了不少,但是因为先行浅拷贝了一手数组,空间消耗上去了,所以我们还要优化一下。
for王遍历法
这种办法其实也是暴力解法,只是跟第一个的思路不一样。第一个解法的思路是遍历0到100000,查出最小的。这个是遍历数组。
var findClosestNumber = function(nums) {
let min = 100000;
for(let i=0;i<nums.length;i++){
if(nums[i]<0){
min = min>-nums[i]?-nums[i]:min;
}else{
min = min>nums[i]?nums[i]:min;
}
if(min == 0)return 0;
}
if(nums.includes(min)){
return min;
}else{
return -min;
}
};
虽然是暴力,但是结果还是很香的。空间消耗要少了一些。
排序
这个排序的话跟第二个排序不太一样,这个排序的时候带着条件。不再是按照值的大小进行排序,而是按照值的绝对值的大小进行排序。
var findClosestNumber = function(nums) {
nums.sort((a,b)=>Math.abs(a)-Math.abs(b));
if(nums[0] < 0&&nums.includes(-nums[0])){
return -nums[0];
}else{
return nums[0];
}
};
这样写虽然代码简洁了许多,但是时间消耗与空间消耗却比上一个for王算法更大。