Q238 除自身以外数组的乘积

本题本质上是 前缀积 + 后缀积 问题,属于前缀和思想在乘法上的扩展。

![](Pasted image 20260605202341.png)

这也是道前缀和类型的题,准确的说,这是一道前缀乘积。

我们看题,可以得到,他想要的效果其实就是把除了自身以外的数的积求出。

假设某个数组为 [a, b, c, d, e]
要求 answer[c],则有
answer[c] = a * b * d * e
即 前缀乘积 × 后缀乘积。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class PrefixSuffixProduct
{public:
    vector<int> prefix;
    vector<int> suffix;
    PrefixSuffixProduct(vector<int>& nums)
    {
        int sz = nums.size();
        prefix.resize(sz+1,1);
        suffix.resize(sz+1,1);
        for(int i=1;i<=sz;i++)
        {
            prefix[i] = prefix[i-1] * nums[i-1];
        }
        for(int i=sz-1;i>=0;i--)
        {
            suffix[i] = suffix[i+1] * nums[i];
        }
    }
    int plus_matrix(int x1)
    {
        return prefix[x1] * suffix[x1+1];
    }
};

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int> res;
        PrefixSuffixProduct am(nums);
        int sz = nums.size();
        res.resize(sz,1);
        for(int i = 0;i<sz;i++)
        {
           res[i] = am.plus_matrix(i);
        }
        return res;
    }
};

算法思想

  • prefix[i] 表示 nums[0] * nums[1] * ... * nums[i-1](前 i 个元素的乘积)
  • suffix[i] 表示 nums[i] * nums[i+1] * ... * nums[n-1](从 i 到末尾的乘积)
  • 对于下标 i,答案 = prefix[i] * suffix[i+1],即左边所有数的乘积 × 右边所有数的乘积。

时间复杂度

  • 构建前缀/后缀数组:O(n)
  • 计算每个位置的答案:O(n)
  • 总复杂度:O(n)

空间复杂度

  • 前缀/后缀数组各 O(n),结果数组 O(n)(不计入输出时可选 O(1) 额外空间)
  • 当前实现:O(n)

改进建议

  • 可以只用一个输出数组,先从左到右累乘,再从右到左乘一次,将空间优化到 O(1)(不含输出数组)。

示例验证
输入:nums = [1,2,3,4]

  • prefix = [1, 1, 2, 6, 24]
  • suffix = [24, 24, 12, 4, 1]
    计算结果:
    • i=0 → 1 * 24 = 24
    • i=1 → 1 * 12 = 12
    • i=2 → 2 * 4 = 8
    • i=3 → 6 * 1 = 6
      输出 [24,12,8,6],正确。

相关内容