返回
剑指 Offer 66:构建乘积数组的两种解法,解析题意,从左往右与从右往左的分析与实现
后端
2024-02-04 15:45:27
题意解析
给定一个长度为 n 的数组 nums,要求构建一个长度也为 n 的数组 answer,其中 answer[i] 是除下 nums[i] 之外所有元素的乘积。
从左往右解法
思路:
- 定义一个前缀积数组 prefix,其中 prefix[i] 是从 nums[0] 到 nums[i] 的乘积。
- 定义一个后缀积数组 suffix,其中 suffix[i] 是从 nums[i] 到 nums[n-1] 的乘积。
- 对于每个元素 nums[i],answer[i] 可以表示为 prefix[i-1] * suffix[i+1]。
复杂度分析:
时间复杂度:O(n)。
空间复杂度:O(n)。
实现:
def construct_product_array_left_to_right(nums):
n = len(nums)
prefix = [1] * n
suffix = [1] * n
# 计算前缀积
for i in range(1, n):
prefix[i] = prefix[i-1] * nums[i-1]
# 计算后缀积
for i in range(n-2, -1, -1):
suffix[i] = suffix[i+1] * nums[i+1]
# 计算答案
answer = [1] * n
for i in range(n):
answer[i] = prefix[i-1] * suffix[i+1]
return answer
从右往左解法
思路:
与从左往右的解法类似,但我们从右往左计算前缀积和后缀积。
复杂度分析:
时间复杂度:O(n)。
空间复杂度:O(n)。
实现:
def construct_product_array_right_to_left(nums):
n = len(nums)
prefix = [1] * n
suffix = [1] * n
# 计算后缀积
for i in range(n-2, -1, -1):
suffix[i] = suffix[i+1] * nums[i+1]
# 计算前缀积
for i in range(1, n):
prefix[i] = prefix[i-1] * nums[i-1]
# 计算答案
answer = [1] * n
for i in range(n):
answer[i] = prefix[i-1] * suffix[i+1]
return answer
总结
两种解法在时间复杂度和空间复杂度上都是相同的。从左往右的解法更容易理解,但从右往左的解法在某些情况下可能更有效率。