每日一题:数组元素积的符号

87 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情

1822. 数组元素积的符号

已知函数 signFunc(x) 将会根据 x 的正负返回特定值:

  • 如果 x 是正数,返回 1 。
  • 如果 x 是负数,返回 -1 。
  • 如果 x 是等于 0 ,返回 0 。

给你一个整数数组 nums 。令 product 为数组 nums 中所有元素值的乘积。

返回 signFunc(product) 。

 

示例 1:

输入: nums = [-1,-2,-3,-4,3,2,1]
输出: 1
解释: 数组中所有值的乘积是 144 ,且 signFunc(144) = 1

示例 2:

输入: nums = [1,5,0,2,-3]
输出: 0
解释: 数组中所有值的乘积是 0 ,且 signFunc(0) = 0

示例 3:

输入: nums = [-1,1,-1,1,-1]
输出: -1
解释: 数组中所有值的乘积是 -1 ,且 signFunc(-1) = -1

 

提示:

  • 1 <= nums.length <= 1000
  • -100 <= nums[i] <= 100

思路1:

由题解:我们只需要进行遍历乘法相加就好:

/**
 * @param {number[]} nums
 * @return {number}
 */
/**
 * @param {number[]} nums
 * @return {number}
 */
var arraySign = function(nums) {
    let total = nums.reduce((a,b) => a*b)
    if(total > 0){
        return 1
    }else if(total == 0) {
        return 0
    }else{
        return - 1
    }
};

但是!这样计算会出现一个问题:就是数值太大而导致进度丢失:

测试用例:
[1,28,-91,-62,-36,-1,-84,-90,-92,61,6,-58,-60,2,51,-15,-18,-81,87,84,100,-84,-13,-87,-33,72,-72,-59,-79,28,-69,-97,-93,17,67,11,-12,19,5,42,-85,71,-77,-82,26,-58,-51,-14,63,-85,-86,66,47,57,-86,-25,-75,59,-17,-71,89,-78,-42,30,39,61,-96,-30,-29,-92,-90,69,20,65,32,92,44,-71,-18,87,-86,23,-96,-21,-49,-96,-98,35,-11,-1,81,-48,68,5,75,57,-30,-7,32,86,-29,-86,-61,45,-31,-93,-26,-9,86,57,-52,75,68,-58,14,27,-94,47,-38,-44,75,-83,21,-83,43,62,74,97,78,43,54,28,64,-19,-89,88,68,18,-96,-83,-25,-71,88,-84,-24,-61,72,-90,-56,29,46,56,51,16,66,-2,65,-95,16,51,42,61,99,89,-93,59,-99,69,26,-61,21,41,40,-4,-49,3,-96,57,65,72,-41,-77,-4,61,71,-88,21,-95,38,64,92,0,-63].reduce((a,b) => a*b)

最终结果:NaN

思路2:

利用栈记录每次出现的正负情况,如果出现 0 直接返回

/**
 * @param {number[]} nums
 * @return {number}
 */
var arraySign = function(nums) {
    let res = []
    for (const num of nums) {
        if(num > 0){
            res.push(1)
        }else if(num == 0){
            return 0
        }else{
            res.push(-1)
        }
    }
    return res.reduce((a,b) => a*b)
};

但是这样非常傻;我们完全可以用数学的一点点想法优化一下

思路2优化:

创建一个记录元素值乘积的符号res,1 为表示正,-1 表示为负。遍历整个数组,如果元素为正,那么不变,否则令 符号变为 res = - res,最后返回 res

/**
 * @param {number[]} nums
 * @return {number}
 */
var arraySign = function(nums) {
    let res = 1
    for (let i = 0; i< nums.length; i++) {
        if(nums[i] == 0){
            return 0
        }
        if(nums[i] < 0){
            res = -res
        }
    }
    return res
};