题目描述:
给你一个二进制串 s (一个只包含0
和 1
的字符串),我们可以将 s 分割成 3 个 非空 字符串 s1
, s2
, s3
(s1 + s2 + s3 = s
)。
请你返回分割 s
的方案数,满足s1
,s2
和 s3
中字符 ‘1’ 的数目相同。
由于答案可能很大,请将它对 10^9 + 7
取余后返回。
示例 1:
输入:s = "10101"
输出:4
解释:总共有 4 种方法将 s 分割成含有 '1' 数目相同的三个子字符串。
"1|010|1"
"1|01|01"
"10|10|1"
"10|1|01"
示例 2:
输入:s = "1001"
输出:0
示例 3:
输入:s = "0000"
输出:3
解释:总共有 3 种分割 s 的方法。
"0|0|00"
"0|00|0"
"00|0|0"
示例 4:
输入:s = "100100010100110"
输出:12
提示:
s[i] == ‘0’ 或者 s[i] == ‘1’
3 <= s.length <= 10^5
解题思路:
1)、vector<int> vI
:记录所有‘1’
的位置;
2)、当 vI.size() == 0
: 不存在‘1’
的位置;计算方式是
“0000”
1:当一个切分点含有2个‘0’时, 有一种方式; 1
2:当一个切分点含有1个‘0’时,第二个切分点有两种选择2个‘0’和一个‘0’, 有一种方式; 2
(1 + 2) * 2 / 2 = 3 种 ;
3)、当‘1’的个数不是3 的倍数,则 输出 0 ;
3)、当存在 3的倍数的‘1’的位置信息;
int first , second ;
first = vI[numI] - vI[numI - 1] ;
second = vI[numI << 1] - vI[(numI << 1) - 1] ;
ret = (long long) first * second ;
ret
即为所要求的切分的个数;
代码实现:
class Solution {
public:
int numWays(string s) {
vector<int> vI ;
int i , numI ;
long long ret = 0 ;
for (i = 0 ; i < s.length() ; i ++)
if (s[i] == '1') vI.push_back(i) ;
//当没有‘1’的时候
if (vI.size() == 0)
{
long long tmp = s.length() - 2 ;
ret = (tmp + 1) * tmp / 2 ;
return ret % 1000000007 ;
}
if (vI.size() % 3 != 0)
return 0 ;
else numI = vI.size() / 3 ;
//当‘1’的个数 == 3i的时候;
int first , second ;
first = vI[numI] - vI[numI - 1] ;
second = vI[numI << 1] - vI[(numI << 1) - 1] ;
ret = (long long) first * second ;
return ret % 1000000007 ;
}
};
复杂度计算:
时间复杂度:O(n)
;
空间复杂度:O(n)
; 存储‘1’的位置信息的消耗;