普通数组——除了自身以外数组的乘积
题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(n) 时间复杂度内完成此题。
这道题的核心要求很明确:不能用出发、时间复杂度O(n)、空间最哟,解法是左右乘积列表(前缀×后缀)。
解题思路
- 前缀乘积:prefix[i] = nums[0]到nums[i-1]的乘积(当前元素左边所有数的乘积)
- 后缀乘积:suffix[i] = nums[i+1]到nums[n-1]的乘积(当前元素右边所有数的乘积)
- 结果:answer[i]= prefix[i] *suffix[i]
我们可以直接用结果数组存储前缀,再反向遍历乘后缀,实现空间O(1)(除结果外无额外空间)。
复杂度
- 时间复杂度:O (n)(仅两次遍历数组)
- 空间复杂度:O (1)(仅用了一个变量 suffix,结果数组不计入额外空间)
总结:
核心:前缀乘积×后缀乘积,避开除法
技巧:用结果数组存储前缀,再反向遍历计算后缀并合并,省空间
满足题目所有要求:O(n)时间、无除法、32位整数安全
完整代码实现如下:
#include
#include
using namespace std;
vector
int n = nums.size();
// 结果数组
vector
// 第一步:计算 前缀乘积(左边所有数乘积),存入 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
vector
cout << "结果:";
for (int num : ans) {
cout << num << " ";
}
// 输出:24 12 8 6
return 0;
}
浙公网安备 33010602011771号