给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
提示:题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
如果不考虑时间复杂度,暴力法可以简单的求解
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
if not nums: return []
res = []
for i in range(len(nums)):
others = nums[:i] + nums[i + 1:]
ans = 1
for n in others:
ans *= n
res.append(ans)
return res
正确的方法是构建前缀乘积数组L和后缀乘积数组R,最终的结果是两个数组对应索引乘积成果组成的数组。两个数组的构建和元素相乘都是O(N)的线性时间复杂度,因此,整体的时间复杂度为O(N)。由于需要辅助数组的使用,因此空间复杂度为O(N)。
详细的思路看官方题解就好啦,这里就不再细写,毕竟我第一次做这个题并不能想到这种做法-_-!
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
length = len(nums)
L, R = [1] * length, [1] * length
res = []
for i in range(1, length):
L[i] = nums[i - 1] * L[i - 1]
for i in range(length - 2, -1, -1):
R[i] = nums[i + 1]* R[i + 1]
for i, j in zip(L, R):
res.append(i * j)
return res
2020 - 7 - 19 更新Java AC Code,如下所示:
/**
* @Author dyliang
* @Date 2020/7/19 22:12
* @Version 1.0
*/
public class ProductExceptSelf {
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4};
int[] res = productExceptSelf(nums);
System.out.println(Arrays.toString(res)); // [24, 12, 8, 6]
}
public static int[] productExceptSelf(int[] nums) {
if (nums.length == 0 || nums.length == 1){
return nums;
}
int len = nums.length;
// 创建前缀数组和后缀数组,并初始化
int[] L = new int[len];
int[] R = new int[len];
L[0] = 1;
R[len - 1] = 1;
for (int i = 1; i < len; i++) {
L[i] = nums[i - 1] * L[i - 1];
}
for(int i = len - 2; i >= 0; i--){
R[i] = nums[i + 1] * R[i + 1];
}
for (int i = 0; i < len; i++) {
L[i] = L[i] * R[i];
}
// 这里直接复用了L,更好的选择是全程只使用L
// 计算后缀数组的结果后,直接和前缀数组中对应的值相乘,然后更新保存到前缀数组
return L;
}
}