5492. 分割字符串的方案数

题目描述:

给你一个二进制串 s (一个只包含01的字符串),我们可以将 s 分割成 3 个 非空 字符串 s1, s2, s3s1 + s2 + s3 = s)。

请你返回分割 s的方案数,满足s1s2s3中字符 ‘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’的位置信息的消耗;

猜你喜欢

转载自blog.csdn.net/u010155337/article/details/108434764
今日推荐