【面试题】除自身以外数组的乘积(三种解法)

题目描述

在这里插入图片描述

解法一:构造前、后缀乘积数组

class Solution(object):
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        left = [1]+ [0]*(len(nums)-1) # 第一个元素左边没有元素,则前缀乘积记为 1
        right = [0]*(len(nums)-1) + [1] # 最后一个元素右边没有元素,则后缀乘积记为 1
        res = []
        for i in range(1, len(nums)): # left[i] 为索引 i 左侧所有元素的乘积
            left[i] = left[i-1]*nums[i-1]
        for j in range(len(nums)-2, -1, -1): # right[j] 为索引 j 右侧所有元素的乘积
            right[j] = right[j+1]*nums[j+1]
        for k in range(len(nums)): # 除 nums[i] 之外其余各元素的乘积就是索引 i左侧所有元素的乘积乘以索引 i右侧所有元素的乘积
            res.append(left[k]*right[k])
        return res

时间复杂度:O(n),三轮for循环
空间复杂度:O(n),申请了两个额外数组 left和right

改进为空间复杂度 O(1)的方法

在这里插入图片描述

class Solution(object):
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        res = [1]+[0]*(len(nums)-1) # res[i] 表示索引 i 左侧所有元素的乘积,第一个元素左边没有元素,所以 res[0]=1
        for i in range(1, len(nums)):
            res[i] = res[i-1]*nums[i-1]
        # R 为右侧所有元素的乘积, 从后往前遍历,刚开始右边没有元素,所以 R = 1
        R = 1 
        for i in range(len(nums)-1, -1, -1):
            res[i] *= R # 对于索引 i的元素,左边所有元素的乘积为 answer[i],右边所有元素的乘积为 R
            R *= nums[i] # R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上

        return res

解法二:构造乘积矩阵

class Solution(object):
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        '''
        nums = [1, 2, 3, 4]
                nums[0]  nums[1]  nums[2]  nums[3]
        res[0]    1         2        3        4
        res[1]    1         1        3        4 
        res[2]    1         2        1        4
        res[3]    1         2        3        1

        分别计算矩阵的上三角和下三角,并存储过程值。遍历两遍 nums即可得到结果
        '''
        res = [1]
        bottom_mul = 1 # 下三角中的乘积过程值
        top_mul = 1 # 上三角中的乘积过程值
        # 计算下三角
        for i in range(len(nums)-1): # 因为下三角中最大也不会取到 num最后一个元素,因此只遍历到 nums倒数第二个元素即可
            bottom_mul *= nums[i]
            res.append(bottom_mul)
        # 计算上三角
        for j in range(len(nums)-1, 0, -1): # 因为上三角中最小也不会取到 num第一个元素,因此从后往前遍历到 nums第二个元素即可
            top_mul *= nums[j]
            res[j-1] *= top_mul
        return res

时间复杂度:O(n),两轮 for循环
空间复杂度:O(1),申请了两个变量 bottom_mul和 top_mul

参考

题解一
题解二

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值