zoukankan      html  css  js  c++  java
  • JS leetcode 寻找数组的中心索引 题解分析

    壹 ❀ 引

    今天是的题目来自leetcode的724. 寻找数组的中心索引,做完之后我感觉自己像个憨憨,题目描述如下:

    给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。

    我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。

    如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。

    示例 1:

    输入: 
    nums = [1, 7, 3, 6, 5, 6]
    输出: 3
    解释: 
    索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
    同时, 3 也是第一个符合要求的中心索引。
    

    示例 2:

    输入: 
    nums = [1, 2, 3]
    输出: -1
    解释: 
    数组中不存在满足此条件的中心索引。
    

    说明:

    • nums 的长度范围为 [0, 10000]。
    • 任何一个 nums[i] 将会是一个范围在 [-1000, 1000]的整数。

    我们先分析,先说说我的实现思路,再来分享其他用户优质解答。

    贰 ❀ 憨憨做法

    题目想传达的意思其实很明确了,当遍历到 i 时, i 左边所有元素(不包括i)的和与 i 右边所有元素(不包括i)的和相等,如果遍历过程中满足则返回 i,如果不满足则返回 -1。

    我第一想到的就是每次遍历 i ,将数组左右分别拆分成两个数组,求和做比较,如果满足则返回 i ,如果未找到返回 -1;

    事先提示这道题的坑,按照我的理解,比如一个数组[1,-1,1],其实只用比较i为1的情况。

    因为当i为0时左边不存在元素,没比较的必要,i为2时右边没元素,也没必要比较,所以我最初循环的条件为:

    for (var i = 1; i < nums.length - 1; i++) {}
    

    然后提交就挂掉了,提示应该返回0而不是-1,也就是按照官方的理解,i为0时左边虽然没元素但和为0(我服了...)。

    经过修改这里提供我的实现,比较粗暴:

    /**
     * @param {number[]} nums
     * @return {number}
     */
    var pivotIndex = function(nums) {
        var i = 0,
            // 左边的和
            sum_l = 0,
            // 右边的和
            sum_r = 0,
            len = nums.length;
        for (; i < len; i++) {
            // 由于i从0开始,nums[0 - 1]为undefined,计算会让结果变成NaN
            if(nums[i - 1]){
                sum_l += nums[i - 1];
            };
    		// 截取i右边的数组求和
            nums.slice(i + 1).map(item => {
                sum_r += item;
            });
            // 比较判断,符合返回i
            if (sum_l == sum_r) {
                return i;
            } else {
                //每次比较完重置右边的和,免得遍历一次越来越大
                sum_r = 0;
            };
        };
        return -1;
    };
    

    提交一看时间,我人都傻了...

    真是要了老命的算法,用了2S...

    叁 ❀ 更佳的做法

    其实按照题目描述,我们可以知道数组所有元素的总和等于i+i左边和+i右边和,所以得出多种公式:

    //左边的和 = (总和 - i)除以2
    sumLeft = (sum - i)/2
    //或者
    sumLeft = sum - i - sumLeft
    

    贴上实现代码:

    /**
     * @param {number[]} nums
     * @return {number}
     */
    var pivotIndex = function (nums) {
        var i = 0,
            len = nums.length,
            sum = 0,
            sumLeft = 0;
        // 求数组总和
        nums.map(item => sum += item);
        // 考虑左边没元素默认为0的情况,所以i为0时不进行sumLeft+=nums[i]的操作
        for (; i < len; i++) {
            if ((sum - nums[i]) / 2 === sumLeft) {
                return i;
            };
            sumLeft += nums[i];
        };
        return -1;
    };
    

    其实唯一需要注意的就是我前面说的坑,i为0时默认左边为0,所以我们是判断了一次后才执行sumLeft += nums[i]

    那么关于本题就说到这了。

  • 相关阅读:
    vim中ctags应用
    LCD屏参数及应用举例
    modbus概述
    Modbus常用
    git常用操作
    linux内核学习
    截图工具gsnap
    信号signal编号及意义及一般处理
    oracle 表空间 数据文件 表的关系
    IBM MQ 2035 或 2013认证错误的解决方法
  • 原文地址:https://www.cnblogs.com/echolun/p/12989350.html
Copyright © 2011-2022 走看看