在Python中查找将数组拆分为三个子数组的方法的数量
假设有一个名为nums的数组,我们必须找到将该数组拆分为子数组nums的良好方法数。答案可能太大,因此返回结果模10 ^ 9 + 7。这是一个数组(具有整数元素)的分割情况良好,如果该数组分成三个从左到右的非空连续子数组,并且左侧中元素的总和小于或等于中部元素的总和,并且中部元素的总和小于或等于右侧元素的总和,那么就是良好的。
因此,如果输入为nums = [2,3,3,3,7,1],则输出将是3,因为有三种不同的拆分方式,
- [2],[3],[3,3,7,1]
- [2],[3,3],[3,7,1]
- [2,3],[3,3],[7,1]
要解决此问题,我们将遵循以下步骤:−
- n:= nums的大小,
- m:= 10 ^ 9 + 7
- ss:=大小为(1 + n)的数组,并进行填充0
- 对于nums中的每个索引i和值val,执行以下操作:
- ss [i]:= ss [i-1] + val
- r:= 0,rr:= 0,ans:= 0
- 对于l在范围1到n-2,执行以下操作:
- r:= r和l + 1的最大值
- 当r < n-1且ss [r] – ss [l] < ss [l]时,执行以下操作
- r:= r + 1
- rr:= rr和r的最大值
- 当rr < n-1且ss [n] – ss [rr + 1] > = ss [rr + 1] – ss [l]时,执行以下操作
- rr:= rr + 1
- 如果ss [l] > ss [r] – ss [l],则
- 从循环中退出
- 如果ss [r] – ss [l] > ss [n] – ss [r],则
- 进入下一轮迭代
- ans:=(ans + rr-r + 1)模m
- 返回ans
示例
让我们看一下以下实现,以便更好地理解−
def solve(nums):
n, m = len(nums), 10**9+7
ss = [0] * (1+n)
for i, val in enumerate(nums, 1):
ss[i] = ss[i-1] + val
r = rr = ans = 0
for l in range(1, n-1):
r = max(r, l+1)
while r < n-1 and ss[r]-ss[l] < ss[l]:
r += 1
rr = max(rr, r)
while rr < n-1 and ss[n]-ss[rr+1] >= ss[rr+1]-ss[l]:
rr += 1
if ss[l] > ss[r]-ss[l]:
break
if ss[r]-ss[l] > ss[n]-ss[r]:
continue
ans = (ans+rr-r+1) % m
return ans
nums = [2,3,3,3,7,1]
print(solve(nums))
输入
[1,7,3,6,5]
输出
3