每日一题——LeetCode1588.所有奇数长度子数组的和

方法一 暴力循环

 遍历数组的每一个元素,找寻该元素所有连续长度为奇数的可能,累加奇数长度区间内的所有元素。

比如对于[1,4,2,5,3] ,对于第一个元素1,有[1]、[1,4,2]、[1,4,2,5,3]这三种可能,对于第二个元素4,有[4]、[4,2,5]这两种可能,以此类推,反复累加最后得到sum

var sumOddLengthSubarrays = function(arr) {
    let  sum=0
    for(let i=0;i<arr.length;i++){
        for(let len=1;i+len<=arr.length;len+=2){
            let end=i+len-1
            for(let j=i;j<=end;j++){
                sum+=arr[j]
            }
        }
    }
    return sum
};

消耗时间和内存情况:

方法二 前缀和

对于方法一中循环求每种可能的奇数长度数组的和可以进行优化,能少嵌套一层for循环

构造前缀和数组prefixSums,数组每一项prefixSums[i]保存的是数组arr从下标0到下标i-1的元素和

var sumOddLengthSubarrays = function(arr) {
    let  sum=0
    let prefixSums = new Array(arr.length+1).fill(0)
    for(let i=0;i<arr.length;i++){
        prefixSums[i+1]=prefixSums[i]+arr[i]
    }
    for(let i=0;i<arr.length;i++){
        for(let len=1;i+len<=arr.length;len+=2){
            let end=i+len-1
            sum+=prefixSums[end+1]-prefixSums[i]
        }
    }
    return sum
};

消耗时间和内存情况:

方法三 数学

大致思路是:

数组中每个元素都会在不同长度的奇数子数组中出现一次或多次,只要计算出每个元素在多少个长度为奇数的子数组中出现,就能得到所有奇数长度子数组的和


作者:力扣官方题解
链接:leetcode1588.所有奇数长度子数组的和

var sumOddLengthSubarrays = function(arr) {
    let sum = 0;
    const n = arr.length;
    for (let i = 0; i < n; i++) {
        const leftCount = i, rightCount = n - i - 1;
        const leftOdd = Math.floor((leftCount + 1) / 2);
        const rightOdd = Math.floor((rightCount + 1) / 2);
        const leftEven = Math.floor(leftCount / 2) + 1;
        const rightEven = Math.floor(rightCount / 2) + 1;
        sum += arr[i] * (leftOdd * rightOdd + leftEven * rightEven);
    }
    return sum;
};

消耗时间和内存情况:

  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值