Given an array of n integers where n > 1, nums
, return an array output
such that output[i]
is equal to the product of all the elements of nums
except nums[i]
.
Solve it without division and in O(n).
For example, given [1,2,3,4]
, return [24,12,8,6]
.
Follow up:
Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.)
给定一个数组,返回一个新数组,数组元素是除了这个位置的数以外其他位置上数的乘积,并要求时间复杂度O(n),不能使用除法。
对于某一位的数字,如果知道其前面所有数字的乘积,同时也知道后面所有数字的乘积,二者相乘就是结果。所以只要分别创建出这两个数组即可,分别从数组的前后两个方向遍历数组,分别建立DP乘积累积数组。
dp1[i+1] = dp[i] * nums[i],i = [0, n-1]
dp2[i-1] = dp[i] * nums[i], i = [n-1, 0]
output[i] = dp1[i] * dp2[i]
还可以优化空间,由于最终的结果都是要乘到结果res中,所以可以不用单独的数组来保存乘积,而是直接累积到res中,先从前面遍历一遍,将乘积的累积存入res中,然后从后面开始遍历,累计到res中。
Java:
class Solution { public int[] productExceptSelf(int[] nums) { int[] result = new int[nums.length]; int[] t1 = new int[nums.length]; int[] t2 = new int[nums.length]; t1[0]=1; t2[nums.length-1]=1; //scan from left to right for(int i=0; i<nums.length-1; i++){ t1[i+1] = nums[i] * t1[i]; } //scan from right to left for(int i=nums.length-1; i>0; i--){ t2[i-1] = t2[i] * nums[i]; } //multiply for(int i=0; i<nums.length; i++){ result[i] = t1[i] * t2[i]; } return result; } }
Java: Space: O(1)
public int[] productExceptSelf(int[] nums) { int[] result = new int[nums.length]; result[nums.length-1]=1; for(int i=nums.length-2; i>=0; i--){ result[i]=result[i+1]*nums[i+1]; } int left=1; for(int i=0; i<nums.length; i++){ result[i]=result[i]*left; left = left*nums[i]; } return result; }
Python:
class Solution(object): def productExceptSelf(self, nums): """ :type nums: List[int] :rtype: List[int] """ res = [0] * len(nums) left = [1] * len(nums) for i in xrange(1, len(nums)): left[i] = left[i-1] * nums[i-1] right = [1] * len(nums) for j in reversed(xrange(len(nums) - 1)): right[j] = right[j+1] * nums[j+1] for i in xrange(len(nums)): res[i] = left[i] * right[i] return res
Python:
class Solution: # @param {integer[]} nums # @return {integer[]} def productExceptSelf(self, nums): if not nums: return [] left_product = [1 for _ in xrange(len(nums))] for i in xrange(1, len(nums)): left_product[i] = left_product[i - 1] * nums[i - 1] right_product = 1 for i in xrange(len(nums) - 2, -1, -1): right_product *= nums[i + 1] left_product[i] = left_product[i] * right_product return left_product
C++:
class Solution { public: vector<int> productExceptSelf(vector<int>& nums) { if (nums.empty()) { return {}; } vector<int> left_product(nums.size()); left_product[0] = 1; for (int i = 1; i < nums.size(); ++i) { left_product[i] = left_product[i - 1] * nums[i - 1]; } int right_product = 1; for (int i = static_cast<int>(nums.size()) - 2; i >= 0; --i) { right_product *= nums[i + 1]; left_product[i] = left_product[i] * right_product; } return left_product; } };
C++:
class Solution { public: vector<int> productExceptSelf(vector<int>& nums) { int n = nums.size(); vector<int> fwd(n, 1), bwd(n, 1), res(n); for (int i = 0; i < n - 1; ++i) { fwd[i + 1] = fwd[i] * nums[i]; } for (int i = n - 1; i > 0; --i) { bwd[i - 1] = bwd[i] * nums[i]; } for (int i = 0; i < n; ++i) { res[i] = fwd[i] * bwd[i]; } return res; } };
C++:
class Solution { public: vector<int> productExceptSelf(vector<int>& nums) { vector<int> res(nums.size(), 1); for (int i = 1; i < nums.size(); ++i) { res[i] = res[i - 1] * nums[i - 1]; } int right = 1; for (int i = nums.size() - 1; i >= 0; --i) { res[i] *= right; right *= nums[i]; } return res; } };