原文链接: https://leetcode-cn.com/problems/number-of-ways-to-split-a-string
英文原文
Given a binary string s
(a string consisting only of '0's and '1's), we can split s
into 3 non-empty strings s1, s2, s3 (s1+ s2+ s3 = s).
Return the number of ways s
can be split such that the number of characters '1' is the same in s1, s2, and s3.
Since the answer may be too large, return it modulo 10^9 + 7.
Example 1:
Input: s = "10101" Output: 4 Explanation: There are four ways to split s in 3 parts where each part contain the same number of letters '1'. "1|010|1" "1|01|01" "10|10|1" "10|1|01"
Example 2:
Input: s = "1001" Output: 0
Example 3:
Input: s = "0000" Output: 3 Explanation: There are three ways to split s in 3 parts. "0|0|00" "0|00|0" "00|0|0"
Example 4:
Input: s = "100100010100110" Output: 12
Constraints:
3 <= s.length <= 10^5
s[i]
is'0'
or'1'
.
中文题目
给你一个二进制串 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的下标索引即可,根据长度数学求解。
若长度不被3整除,说明无论如何也不能等分3份(每份1的个数和即3等分的宽度),解为0
若长度为0,说明没有1,则是原先字符串长度-1中(想象成有n-1个槽)选2个槽拆分,即则结果为组合C问题
(n-1)*(n-2)/2!
否则,即把新数组news拆分成3等分,其解为1,2等分索引差值2,3等分索引差值,why?
首先开头结尾无论有多少0,不影响结果,结果只和中间0个数有关,具体的只和拆分点后面的0个数有关,为(len(news)/3-len(news)/3-1)*(len(news)/3*2-len(news)/3*2-1)
举个例子”0100100010”,对应1的索引数组[1,4,8],解为(4-1)(8-4),第一个1后面有2个0,则加上本身的共3种情况(01,010,0100),第二个1后面有3个0,则加上本身共4种情况(1,10,100,1000)
“101010010001010000000”,索引数组为[0,2,4,7,11,13],则解只和拆分点2,4及7,11有关,即(4-2)*(11-7),理解为中间的变数一定是拆分点后面0的个数引起的,有几个0就直接数0的个数+1相乘即可
比赛时我也是算了好久才明白,压根就是数学题!!!
若思路觉得还可以,欢迎大家点赞支持。
代码
class Solution:
def numWays(self, s: str) -> int:
news = [i for i,num in enumerate(s) if num=='1']
k = len(news)
if k%3:return 0
if not k:return (len(s)-1)*(len(s)-2)//2%1000000007
return (news[k//3]-news[k//3-1])*(news[k//3*2]-news[k//3*2-1])%1000000007
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
4634 | 15596 | 29.7% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|