题目描述:
思路:
时间要求为O(n),且不能用除法——空间换时间?遍历过程保存遍历过的数的乘积?
解决方案:
维护乘积数组:维护两个数组L、R,L[i]与R[i]表示数组i除自己外左边乘积或右边乘积。对于头尾元素,L[0]与R[nums.size() - 1]设置为1. L[i] = L[i - 1]与nums[i]的乘积(因为L[i - 1]表示nums[i]左边所有元素的乘积,不包括nums[i])。R[i]同理。
#include#include using namespace std; vector productExceptSelf(vector & nums) { //左右数组乘机:维护两个数组L、R,L[i]与R[i]表示除自己nums[i]外左边所有数乘积或右边所有数 //乘积 vector L(nums.size(), 0); vector R(nums.size(), 0); L[0] = 1; for (int i = 1; i < nums.size(); i++) { L[i] = L[i - 1] * nums[i - 1]; } R[nums.size() - 1] = 1; for (int i = nums.size() - 2; i >= 0; i--) { R[i] = R[i + 1] * nums[i]; } for (int i = 0; i < nums.size(); i++) { L[i] *= R[i]; } return L; }
时间复杂度为O(n),空间复杂度为O(n).
能否优化?
只需要L数组,对于R数组动态构造,构造过程:
L数组构造完成后,由于没有R数组,从前向后遍历无法得出答案,考虑从后向前
i = nums.size() - 1时,R = 1,L[i] = L[i] * R,更新完L[i]后,更新R,R = R * nums[i]
迭代直至结束。
#include#include using namespace std; vector productExceptSelf(vector & nums) { //维护两个数组L,L[i]数组i除自己外左边乘积 vector L(nums.size(), 0); //优化:空间复杂度优化为O(1) 只使用L数组,对R数组动态构建 for (int i = 1; i < nums.size(); i++) { L[i] = L[i - 1] * nums[i - 1]; } int R = 1; for (int i = nums.size() - 1; i >= 0; i--) { L[i] = L[i] * R; R *= nums[i]; } return L; }



