寻找数组的中心下标

420 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

  • 给你一个整数数组 nums ,请计算数组的 中心下标
  • 数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
  • 如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
  • 如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
  • 示例 1:
    • 输入: nums = [1, 7, 3, 6, 5, 6]
    • 输出: 3
    • 解释:中心下标是 3 。左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。
  • 示例 2:
    • 输入: nums = [1,2,3]
    • 输出: -1
    • 数组中不存在满足此条件的中心下标。
  • 示例 3:
    • 输入: nums = [2,1,-1]
    • 输出: 0
    • 中心下标是 0 。左侧数之和 sum = 0 ,(下标 0 左侧不存在元素),右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。
  • 提示:
    • 1 <= nums.length <= 10000
    • -1000 <= nums[i] <= 1000

二、思路分析:

  • 中心数有四种情况
    • 第一种:数组第一位为中心数,可能后面有其他中心数
    • 第二种:数组最后一位为中心数,可能前面有其他中心数
    • 第三种:数组中间某一位或几位是中心数
    • 第四种:数组没有中心数
  • 这里定义了两个变量leftright用来保存中心数左边和右边的和
  • 第一种情况:
    • 当数组第一位为中心数时,左边的和默认是0,只需要将右边的和累加起来即可
    • 遍历数组,去除掉当前数字本身,遍历参数应当从1开始
    • 如果累加后的左边和等于右边和,说明数组第一个值是中心数,因为可能有多个,先保存到数组变量中
  • 第二种情况:
    • 当数组最后一位为中心数时,右边的和默认是0,只需要将左边的和累加起来即可
    • 遍历数组,去除掉当前数字本身,遍历参数应当小于数组长度减去1
    • 如果累加后的左边和等于右边和,说明数组最后一个值是中心数,因为可能有多个,先保存到数组变量中
  • 第三种情况:
    • 当数组中心数在中间某一项时,需要将数组的左边和右边分别统计出来
    • 统计左边的和,范围应当是0 ~ i并且包括i
    • 统计右边的和,范围应当是i+1 ~ nums.length - 1
    • 如果累加后的左边和等于右边和,说明当前项是中心数,因为可能有多个,先保存到数组变量中
  • 第四种情况:
    • 遍历完数组后,如果数组长度为0,说明没有中心数,直接返回-1
  • 其他:数组中有中心数,不管有几个,将数组升序排序,返回第一个值,即最小的中心数

三、AC 代码:

function pivotIndex(nums: number[]): number {
    let result = [];
    for(let i = 0; i < nums.length; i++){    
        let left = 0;
        let right = 0;
        if(i === 0) {
            for(let j = 1; j < nums.length; j++){
                right += nums[j];
            }
            if(right === left){
                result.push(0);
                break;
            }
        }
        if(i === nums.length - 1){
            for(let j = 0; j < nums.length - 1; j++){
                left += nums[j];
            }
            if(right === left){
                result.push(nums.length - 1);
                break;
            }
        }
        for(let l = 0; l < i; l++){
            left += nums[l]
        }
        for(let r = nums.length - 1; r > i; r--){
            right += nums[r]
        }
        if(right === left) result.push(i)

    }
    if(!result.length) return -1
    result.sort((a, b) => { return a - b })
    return result[0];
};

四、总结:

  • 分好情况后还是比较简单的,当然还有其他复杂度低的方法,这里就不写了
  • 更多解题方式,移步题解区

image.png