📅  最后修改于: 2023-12-03 15:07:17.445000             🧑  作者: Mango
给定一个数组 nums
,编写一个函数来计算
0 <= i < nums.length
之间,存在多少个下标位置,满足 nums[0] * nums[1] * ... * nums[i-1] == nums[i+1] * nums[i+2] * ... * nums[nums.length-1]
。注意:空数组 nums
的乘积是 1。
我们可以使用前缀和与后缀积来让该题变得更加容易解决。
具体的,我们可以使用函数 $p_k$ 记录下标 $k$ 左侧所有数字的乘积,使用函数 $s_k$ 记录下标 $k$ 右侧所有数字的乘积。
这样一来,当我们枚举下标 $i$ 时,对 $p_{i-1}$ 与 $s_{i+1}$ 相乘判定是否相等即可。
实际上,我们可以使用两个循环来遍历数组,先填充前缀积和后缀积的数组,然后从头到尾枚举下标计算即可。
时间复杂度 $O(n)$。
from typing import List
class Solution:
def numSubarrayProductEqualssum(self, nums: List[int]) -> int:
n = len(nums)
p, s = [1] * n, [1] * n
for i in range(1, n):
p[i] = p[i - 1] * nums[i - 1]
for i in range(n - 2, -1, -1):
s[i] = s[i + 1] * nums[i + 1]
res = 0
for i in range(n):
if p[i] * s[i] == p[-1]:
res += 1
return res
前缀和与后缀积是一种非常有用的技巧,可以大大提升某些问题的解决效率。此题便是其中之一。
在实现中,我们可以先将前缀积和后缀积计算好,再一起使用,可以减少一些不必要的计算,降低时间复杂度。