题目要求不能用除法,按照暴力思路来,那时间复杂度就到了n*n,这个也不符合题意
先来看下之前写的一个解法
这里的解法,有点类似于前缀和的意思,分别把从左往右以及从右往左的乘积计算出来,最后对应位置进行相乘即可,注意处理边界条件即可(22行以及24行代码)。
class Solution {
public int[] productExceptSelf(int[] nums) {
int len = nums.length;
int[] res = new int[len];
if (len == 1) {
return nums;
}
int[] left = new int[len];
int[] right = new int[len];
left[0] = nums[0];
right[len - 1] = nums[len - 1];
for (int i = 1; i < len; ++i) {
// 1 2 3 4 nums
// 1 2 6 24 left
left[i] = nums[i] * left[i - 1];
}
for (int j = len - 2; j >= 0; --j) {
// 24 24 12 4 right
right[j] = nums[j] * right[j + 1];
}
for (int k = 0; k < len; ++k) {
if (k == 0) {
res[k] = right[k + 1];
} else if (k == len - 1) {
res[k] = left[len - 2];
} else {
res[k] = left[k - 1] * right[k + 1];
}
}
return res;
}
}
这里的解法也是跟上面相似,只不过空间复杂度没有上面的高。
先处理从左往右的,除开本身的乘积,然后处理从右往左的
var productExceptSelf = function (nums) {
let len = nums.length
let res = new Array(len).fill(1)
let leftTmp = 1
for (let i = 0; i < len; ++i) {
res[i] = leftTmp
leftTmp *= nums[i]
}
let rightTmp = 1
for (let i = len - 1; i >= 0; --i) {
// 注意这里的处理,需要与右边的相乘
res[i] *= rightTmp
rightTmp *= nums[i]
}
return res
};
对于测试用例[1,2,3,4]
第一轮计算leftTmp之后有 res = [1, 1, 2, 6]
然后计算第二轮for
- 第 1 步(
i = 3):res[3] *= rightTmp = 6 * 1 = 6- 更新
rightTmp = rightTmp * nums[3] = 1 * 4 = 4 - 此时
res = [1, 1, 2, 6]
- 第 2 步(
i = 2):res[2] *= rightTmp = 2 * 4 = 8- 更新
rightTmp = rightTmp * nums[2] = 4 * 3 = 12 - 此时
res = [1, 1, 8, 6]
- 第 3 步(
i = 1):res[1] *= rightTmp = 1 * 12 = 12- 更新
rightTmp = rightTmp * nums[1] = 12 * 2 = 24 - 此时
res = [1, 12, 8, 6]
- 第 4 步(
i = 0):res[0] *= rightTmp = 1 * 24 = 24- 更新
rightTmp = rightTmp * nums[0] = 24 * 1 = 24 - 此时
res = [24, 12, 8, 6]