目录
思路
主要基于数组的前缀和与后缀和的概念。首先,我们需要知道整个数组的总和(
totalSum
),以便在后续计算中可以方便地得到任意位置的右侧元素之和(通过totalSum
减去左侧元素之和和当前位置的元素值)。然后,我们初始化一个变量leftSum
来存储当前位置左侧所有元素的和。通过遍历数组,我们可以动态地更新leftSum
的值,并在每次迭代中计算当前位置的右侧元素之和(rightSum
)。如果leftSum
等于rightSum
,则找到了一个中心下标,直接返回该位置。
解题方法
- 计算总和:首先遍历整个数组,计算所有元素的总和
totalSum
。 - 遍历查找:然后,使用另一个循环遍历数组的每个位置。在每次迭代中,根据
totalSum
和当前leftSum
的值计算rightSum
。 - 判断并返回:如果
leftSum
等于rightSum
,则返回当前位置作为中心下标。如果遍历完数组都没有找到满足条件的位置,则返回-1。
时间复杂度
O(n),其中n是数组nums
的长度。我们需要两次遍历数组:第一次遍历计算总和,第二次遍历查找中心下标。虽然看起来是两次遍历,但总的时间复杂度仍然是线性的,因为两个遍历是独立的,并且每个元素都只被访问了一次。
空间复杂度
O(1),除了存储输入数组nums
所需的空间外(这不计入算法的空间复杂度计算,因为它是输入的一部分),我们只需要几个额外的变量(totalSum
、leftSum
、rightSum
和循环计数器i
)来执行算法。这些变量的数量是固定的,不随输入数组的大小而变化,因此空间复杂度是常量的。
Code
class Solution {
public int pivotIndex(int[] nums) {
if (nums == null || nums.length == 0) {
return -1; // 如果数组为空,则不存在中心下标
}
int totalSum = 0;
for (int num : nums) {
totalSum += num; // 首先计算整个数组的总和
}
int leftSum = 0;
for (int i = 0; i < nums.length; i++) {
int rightSum = totalSum - leftSum - nums[i]; // 计算当前位置右侧的和
if (leftSum == rightSum) {
return i; // 如果左侧和等于右侧和,则返回当前位置作为中心下标
}
leftSum += nums[i]; // 更新左侧和
}
return -1; // 如果没有找到中心下标,则返回-1
}
}