寻找数组的中心下标

标签: 数组 前缀和

难度: Easy

给你一个整数数组 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 <= 104
  • -1000 <= nums[i] <= 1000

注意:本题与主站 724 题相同: https://leetcode-cn.com/problems/find-pivot-index/

Submission

运行时间: 30 ms

内存: 16.9 MB

class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        n = len(nums)
        all_sum = sum(nums)
        pre_sum = 0
        for i in range(n):
            if all_sum - nums[i] - pre_sum == pre_sum:
                return i
            pre_sum += nums[i]
        return -1

Explain

这个题解首先计算整个数组的总和,存储在变量 all_sum 中。然后遍历数组,使用一个变量 pre_sum 来记录当前索引左侧的元素和。在每次循环中,检查当前索引 i 是否是中心下标,即检查除去当前元素 nums[i] 后的剩余元素和是否为 2 倍的 pre_sum(即两侧相等)。如果是,则返回当前索引。如果遍历结束还没有找到符合条件的中心下标,则返回 -1。

时间复杂度: O(n)

空间复杂度: O(1)

class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        n = len(nums)  # 数组长度
        all_sum = sum(nums)  # 数组总和
        pre_sum = 0  # 初始化前缀和为0
        for i in range(n):  # 遍历数组
            if all_sum - nums[i] - pre_sum == pre_sum:  # 判断当前索引是否是中心下标
                return i  # 是则返回该索引
            pre_sum += nums[i]  # 更新前缀和
        return -1  # 没有找到合适的中心下标,返回-1

Explore

这个条件是基于中心下标左侧和右侧的和必须相等的原则。假设 `pre_sum` 是中心下标左侧元素的总和。右侧元素的总和可以表示为 `all_sum - nums[i] - pre_sum`,其中 `all_sum` 是数组的总和,`nums[i]` 是中心下标处的值。因此,如果左侧和等于右侧和,即 `pre_sum == all_sum - nums[i] - pre_sum`,则说明找到了中心下标。直接比较左右两边的和需要额外的变量来记录右侧和,而使用这种方式可以简化计算和空间复杂度。

算法中没有对负数或零进行特殊处理,因为算法逻辑本身适用于包括负数和零在内的任何整数。总和 `all_sum` 和前缀和 `pre_sum` 都会自然地计算这些值。负数和零的存在不会影响算法的正确性,因为算法只是基于数学上的总和来判断,并不依赖于元素的具体值。

如果数组只有一个元素,那么这个元素的索引为0。在这种情况下,`pre_sum` 为0(因为没有左侧元素),右侧也没有元素,所以 `all_sum - nums[0]` 也为0。这满足条件 `all_sum - nums[0] - pre_sum == pre_sum`。因此,算法会返回0,这是符合中心下标的定义的,因为左侧和右侧的元素之和都是0。