【LeetCode 1588. 所有奇数长度子数组的和 】- JavaScript(暴力+规律)

211 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


【LeetCode 1588. 所有奇数长度子数组的和 】- JavaScript(暴力+规律)

题意描述

给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。

子数组 定义为原数组中的一个连续子序列。

请你返回 arr 中 所有奇数长度子数组的和 。

示例 1:

输入:arr = [1,4,2,5,3]

输出:58

解释:所有奇数长度子数组和它们的和为:

[1] = 1 [4] = 4 [2] = 2 [5] = 5 [3] = 3 [1,4,2] = 7 [4,2,5] = 11 [2,5,3] = 10 [1,4,2,5,3] = 15 我们将所有值求和得到 1 + 4 + 2 + 5 + 3 + 7 + 11 + 10 + 15 = 58

思路分析:

很容易可以发现这是一道规律题。每个数字所在的区间有两种情况:

  1. 数左半边区间有奇数个,右半边奇数个;
  2. 数左半区间偶数个,右半区间偶数个;

等价于即左边奇位数*右边奇位数+左边偶位数*右边偶位数

暴力解法

核心思想:如果实在没有想出来规律,不妨冲它一波,暴力出奇迹。具体就是把每个符合要求的数全部加起来就行了。原地累计和

  • 如果奇数为1,把整个数组累加起来。把output初始值设为所有数字累加之后的值。
  • 第二个奇数3开始遍历以3为长度的子数组,把子数组的值都累加到output。
  • 接下来遍历以5为长度的子数组,同理推导,如果长度已经超过了原数组的大小,就停下来

注意点:

  • 时间复杂度为O(n^3)
var sumOddLengthSubarrays = function (arr) {
    var res = 0;
    function handle(arr, nums) {
        for (var i = 0; i < arr.length; i++) {
            var a = arr.slice(i, nums + i);
            if (a.length < nums) {
                break;
            }
            res += a.reduce((a1, b1) => {
                return a1 + b1
            })
        }
    }
    for (var nums = 1; nums <= arr.length; nums += 2) {
        handle(arr, nums);
    }
    return res;
};

完全背包

思想:如果慢慢发现题目的规律,并且总结出来,那么这道题就简单了,将O^3的复杂度直接到O,质的飞跃。就像最开始的我们说的规律,其中一个很重要的逻辑一定要注意奇 + 1 + 奇 = 奇,偶 + 1 + 偶 = 奇。这可以说是关键.那么久回到开头说的即左边奇位数*右边奇位数+左边偶位数*右边偶位数

注意:注意精度问题,避免舍去造成的误差。尤其是js没有整形

var sumOddLengthSubarrays = function (arr) {
    var output = 0;
    var len = arr.length;
    for (let i = 0; i < len; i++) {
        let left = i + 1,
            right = len - i,
            left_odd = Math.floor((left + 1) / 2),
            left_even = Math.floor(left / 2),
            right_odd = Math.floor((right + 1) / 2),
            right_even = Math.floor(right / 2);
        output += (left_even * right_even + left_odd * right_odd) * arr[i];
    }
    return output;
};

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤