給定長度為 n (n > 1) 的整數陣列 nums,返回陣列 output 使得 output[i] 等於除 nums[i] 以外所有元素的乘積。要求:
範例:輸入 [1,2,3,4] → 輸出 [24,12,8,6]
直接計算總乘積再除以各元素雖直觀,但違反「不使用除法」限制,且遇 0 值需特殊處理。標準解法採用左右乘積分解:
output[i] = (nums[0] × ... × nums[i-1]) × (nums[i+1] × ... × nums[n-1])
即 output[i] = leftProduct[i] × rightProduct[i],其中:
leftProduct[i] 為索引 i 左側所有元素乘積rightProduct[i] 為索引 i 右側所有元素乘積利用輸出陣列直接存儲左乘積,再用單一變量累積右乘積:
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int n = nums.size();
vector<int> output(n, 1);
// 正向遍歷:output[i] 存儲 nums[0] 到 nums[i-1] 的乘積
for (int i = 1; i < n; ++i) {
output[i] = output[i-1] * nums[i-1];
}
// 反向遍歷:用 right 累積右側乘積,直接乘到 output[i]
int right = 1;
for (int i = n - 1; i >= 0; --i) {
output[i] *= right;
right *= nums[i];
}
return output;
}
};
| 步驟 | output[i] 含義 | right 變量含義 |
|---|---|---|
| 正向遍歷後 | 左側乘積 (nums[0]...nums[i-1]) | 未使用 |
| 反向遍歷中 | 左側乘積 × 右側乘積 (最終結果) | nums[i+1]...nums[n-1] 的乘積 |
right,輸出陣列不計入左右乘積分解法天然處理 0 值:
無需額外分支判斷,代碼更簡潔健壯。
本題核心在於將「除自身外乘積」分解為「左乘積 × 右乘積」,並通過輸出陣列複用實現 O(1) 空間。此思想廣泛應用於陣列區間乘積/和問題,是陣列前綴後綴分解的經典範例。