leetcode-Product of Array Except Self

https://leetcode.com/problems/product-of-array-except-self/

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.)

分析:

最开始想出来的方法就是愣头愣脑的蠢算,不出所料,肯定是超时的。

然后发现每个乘积两边的数是按照规律增长减少的,便想能不能利用这个规律节约计算时间。

于是发现我可以用左边数的乘积存起来,等到计算下一个乘积的时候只需要拿之前的数乘上左边的数字就可以辣。

至于右边的数是呈递减分布的,如何才能使用它还不得而知。便先写了代码,结果又超时了。。

想了许久仍没有答案,去讨论区看了看别人的c++语言的代码,发现了其中的巧妙之处。

我们的题目要求是:求该数组除本身以外的所有元素之乘积。不能用除法。

于是我们要得到一个列表,这个列表的每个元素为:

[左边元素乘积]x[右边元素乘积]

同时,我们又发现随着往右计算,[左边元素的乘积]是递增的,[右边元素的乘积]则相反。

如何使左边元素的乘积计算量减少刚才我已经想出方法了,那么如何才能使右边元素的乘积计算量减少呢?

其实答案很巧妙,我们可以先从右往左更新结果列表,让里面存储右边元素的乘积,然后

再从左往右乘上左边元素的乘积就可以辣。时间复杂度O(n)。详情看代码:

class Solution:
    # @param {integer[]} nums
    # @return {integer[]}
    def productExceptSelf(self, nums):
        length = len(nums)
        ans = [1]*length
        temp = 1
        for i in range(length-2,-1,-1):  # 从右往左先更新结果列表,使之存储的是右边元素的乘积
            ans[i] *= temp*nums[i+1]
            temp *= nums[i+1]
        temp = 1
        for j in range(1, length):  # 从左往右依次乘上左边元素的乘积
            ans[j] *= temp*nums[j-1]
            temp *= nums[j-1]
        return ans
原文地址:https://www.cnblogs.com/Blaxon/p/4685854.html