除自身以外数组的乘积

GitHub跳转原题关系图返回列表

结果先存左侧前缀积,再乘右侧后缀积,O(n) 时间 O(1) 额外空间。

OJ: leetcodecn

题目 ID: product-of-array-except-self

难度:普及+/提高

标签:数组前缀和cpppython

日期: 2026-07-28 22:05

题意

返回数组 answer,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。不能用除法,O(n) 时间。

思路

最简单想到的是 O(n²) 暴力或先算总积再除以自身(但题目禁止除法且零元素会导致除零)。优化:第一次遍历存左侧前缀积到答案数组,第二次遍历从右侧乘上后缀积。

代码

cpp
/**
 * Author by Rainboy
 */
// main.cpp:左侧前缀积 * 右侧后缀积,O(n) O(1) extra。
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    vector<int> productExceptSelf(vector<int> &nums) {
        int n = nums.size();
        vector<int> ans(n, 1);
        int left = 1;
        for (int i = 0; i < n; i++) {
            ans[i] = left;
            left *= nums[i];
        }
        int right = 1;
        for (int i = n - 1; i >= 0; i--) {
            ans[i] *= right;
            right *= nums[i];
        }
        return ans;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int &x : a)
        cin >> x;
    auto v = Solution().productExceptSelf(a);
    for (int x : v)
        cout << x << ' ';
    return 0;
}
python
#!/usr/bin/env python3
from typing import List


class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        n = len(nums)
        ans = [1] * n
        left = 1
        for i in range(n):
            ans[i] = left
            left *= nums[i]
        right = 1
        for i in range(n - 1, -1, -1):
            ans[i] *= right
            right *= nums[i]
        return ans


def main() -> None:
    n = int(input())
    nums = list(map(int, input().split()))
    print(*Solution().productExceptSelf(nums))


if __name__ == "__main__":
    main()

复杂度

  • 时间复杂度:O(n),两次遍历。
  • 空间复杂度:O(1) 不计答案数组。

总结

"左侧前缀 + 右侧后缀"是避免除法的经典技巧,不需要特殊处理零元素。