🔗 🟢 724. Find Pivot Index

tags: 陣列(Array) 前綴和(Prefix Sum)

題意

給定一個整數陣列 numsnums,請計算這個陣列的 中心索引(Pivot Index)

中心索引(Pivot Index) 是陣列的一個索引,其左側所有元素相加的和等於右側所有元素相加的和。

如果中心索引位於陣列的最左側,那麼左側數之和視為 00,因為沒有元素在索引的左側,如果位於陣列的最右側同理。

如果陣列有多個中心索引,則返回最左側的那一個,如果陣列不存在中心索引,返回 1-1

思路:前綴和(Prefix Sum)

根據題意,若存在中心索引 ii,則有 nums[0]+nums[1]++nums[i1]=nums[i+1]+nums[i+2]++nums[n1]nums[0] + nums[1] + \cdots + nums[i-1] = nums[i+1] + nums[i+2] + \cdots + nums[n-1],其中 nn 為陣列長度。令 tottot 為所有元素的總和,ss 為當前索引 ii 左側所有元素的和,則有 s+nums[i]+s=tots + nums[i] + s = tot,即 2×s+nums[i]=tot2 \times s + nums[i] = tot

由於 s=j=0i1nums[j]s = \displaystyle\sum_{j=0}^{i-1} nums[j],因此可以使用 前綴和(Prefix Sum) 的概念來解決這個問題。在遍歷陣列的過程中,維護一個前綴和 ss,對於每個索引 ii,檢查 2×s+nums[i]==tot2 \times s + nums[i] == tot 是否成立。如果成立,則 ii 就是中心索引;否則則累加 ss 並繼續遍歷。最後,如果不存在這樣的索引,則返回 1-1

複雜度分析

  • 時間複雜度: O(n)\mathcal{O}(n),其中 nn 為陣列的長度。
  • 空間複雜度: O(1)\mathcal{O}(1)
1
2
3
4
5
6
7
8
9
class Solution:
def pivotIndex(self, nums: List[int]) -> int:
tot = sum(nums)
s = 0 # prefix sum
for i, x in enumerate(nums):
if 2 * s + x == tot:
return i
s += x
return -1
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int pivotIndex(vector<int>& nums) {
int n = nums.size();
int tot = accumulate(nums.begin(), nums.end(), 0);
int s = 0; // prefix sum
for (int i = 0; i < n; ++i) {
if ((s << 1) + nums[i] == tot) return i;
s += nums[i];
}
return -1;
}
};

寫在最後

Cover photo is remixed from @吃肥皂泡泡, thanks for their work!