普通数组——除了自身以外数组的乘积

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

请 不要使用除法,且在 O(n) 时间复杂度内完成此题。

这道题的核心要求很明确:不能用出发、时间复杂度O(n)、空间最哟,解法是左右乘积列表(前缀×后缀)。

解题思路

  1. 前缀乘积:prefix[i] = nums[0]到nums[i-1]的乘积(当前元素左边所有数的乘积)
  2. 后缀乘积:suffix[i] = nums[i+1]到nums[n-1]的乘积(当前元素右边所有数的乘积)
  3. 结果:answer[i]= prefix[i] *suffix[i]

我们可以直接用结果数组存储前缀,再反向遍历乘后缀,实现空间O(1)(除结果外无额外空间)。

复杂度

  • 时间复杂度:O (n)(仅两次遍历数组)
  • 空间复杂度:O (1)(仅用了一个变量 suffix,结果数组不计入额外空间)

总结:
核心:前缀乘积×后缀乘积,避开除法
技巧:用结果数组存储前缀,再反向遍历计算后缀并合并,省空间
满足题目所有要求:O(n)时间、无除法、32位整数安全

完整代码实现如下:

#include
#include
using namespace std;

vector productExceptSelf(vector& nums) {

int n = nums.size();
// 结果数组
vector res(n);

// 第一步:计算 前缀乘积(左边所有数乘积),存入 res
res[0] = 1; // 第一个元素左边无数字,前缀为 1
for (int i = 1; i < n; ++i) {
res[i] = res[i-1] * nums[i-1];
}

// 第二步:计算 后缀乘积(右边所有数乘积),直接乘到 res 上
int suffix = 1; // 最后一个元素右边无数字,后缀为 1
for (int i = n-1; i >= 0; --i) {
res[i] = res[i] * suffix; // 前缀 × 后缀 = 答案
suffix = suffix * nums[i]; // 更新后缀,包含当前元素
}

return res;
}

// 测试主函数
int main() {

vector nums = {1,2,3,4};
vector ans = productExceptSelf(nums);

cout << "结果:";
for (int num : ans) {
cout << num << " ";
}
// 输出:24 12 8 6
return 0;
}

posted @ 2026-03-29 21:56  ZealousMclaren  阅读(9)  评论(0)    收藏  举报