2750-将数组划分成若干好子数组的方式
给你一个二元数组 nums
。
如果数组中的某个子数组 恰好 只存在 一 个值为 1
的元素,则认为该子数组是一个 好子数组 。
请你统计将数组 nums
划分成若干 好子数组 的方法数,并以整数形式返回。由于数字可能很大,返回其对 109 + 7
取余
之后的结果。
子数组是数组中的一个连续 非空 元素序列。
示例 1:
**输入:** nums = [0,1,0,0,1]
**输出:** 3
**解释:** 存在 3 种可以将 nums 划分成若干好子数组的方式:
- [0,1] [0,0,1]
- [0,1,0] [0,1]
- [0,1,0,0] [1]
示例 2:
**输入:** nums = [0,1,0]
**输出:** 1
**解释:** 存在 1 种可以将 nums 划分成若干好子数组的方式:
- [0,1,0]
提示:
1 <= nums.length <= 105
0 <= nums[i] <= 1
根据题意,需要在每两个 1 之间画一条分割线,有 x 个 0 就可以画 x+1 条分割线。
根据乘法原理,答案为所有分割线的方案数的乘积。这里讲解见【周赛 351】 第三题。
特别地,如果数组中没有 1,那么答案为 0。如果数组只有一个 1,那么答案为 1。
如果你对取模有疑问,可以看文末的讲解。
1 | class Solution: |
1 | class Solution { |
1 | class Solution { |
1 | func numberOfGoodSubarraySplits(nums []int) int { |
复杂度分析
- 时间复杂度:\mathcal{O}(n),其中 n 为 nums 的长度。
- 空间复杂度:\mathcal{O}(1)。仅用到若干额外变量。
相似题目
算法小课堂:模运算
如果让你计算 1234\cdot 6789 的个位数,你会如何计算?
由于只有个位数会影响到乘积的个位数,那么 4\cdot 9=36 的个位数 6 就是答案。
对于 1234+6789 的个位数,同理,4+9=13 的个位数 3 就是答案。
你能把这个结论抽象成数学等式吗?
一般地,涉及到取模的题目,通常会用到如下等式(上面计算的是 m=10):
(a+b)\bmod m = ((a\bmod m) + (b\bmod m)) \bmod m
(a\cdot b) \bmod m=((a\bmod m)\cdot (b\bmod m)) \bmod m
证明:根据带余除法,任意整数 a 都可以表示为 a=km+r,这里 r 相当于 a\bmod m。那么设 a=k_1m+r_1,\ b=k_2m+r_2。
第一个等式:
\begin{aligned}
&\ (a+b) \bmod m\
=&\ ((k_1+k_2) m+r_1+r_2)\bmod m\
=&\ (r_1+r_2)\bmod m\
=&\ ((a\bmod m) + (b\bmod m)) \bmod m
\end{aligned}
第二个等式:
\begin{aligned}
&\ (a\cdot b) \bmod m\
=&\ (k_1k_2m^2+(k_1r_2+k_2r_1)m+r_1r_2)\bmod m\
=&\ (r_1r_2)\bmod m\
=&\ ((a\bmod m)\cdot (b\bmod m)) \bmod m
\end{aligned}
根据这两个恒等式,可以随意地对代码中的加法和乘法的结果取模。