题目是LeetCode第197场周赛的第二题,链接:1513. 仅含 1 的子串数。具体描述为:给你一个二进制字符串s
(仅由'0'
和'1'
组成的字符串)。返回所有字符都为 1 的子字符串的数目。由于答案可能很大,请你将它对10^9 + 7
取模后返回。
示例1:
输入:s = "0110111"
输出:9
解释:共有 9 个子字符串仅由 '1' 组成
"1" -> 5 次
"11" -> 3 次
"111" -> 1 次
示例2:
输入:s = "101"
输出:2
解释:子字符串 "1" 在 s 中共出现 2 次
示例3:
输入:s = "111111"
输出:21
解释:每个子字符串都仅由 '1' 组成
示例4:
输入:s = "000"
输出:0
也挺简单的,先找到字符串中具有连续的1
的这些最长子串(也就是左右都是0
或者到头到尾了),假设其长度为n
,那么可以得到的具有连续1
的子串一共有1+2+...+n=n(n+1)/2
个。找到所有的最长连续1
子串然后加起来就可以了。时间复杂度为
O
(
n
)
O(n)
O(n),空间复杂度为
O
(
1
)
O(1)
O(1)。
JAVA版代码如下:
class Solution {
public int numSub(String s) {
int MOD = 1000_000_007;
int res = 0;
int oneCount = 0;
for (char c : s.toCharArray()) {
if (c == '1') {
++oneCount;
}
else {
res = (res + (int)(((long)oneCount * (long)(oneCount + 1)) % MOD) / 2) % MOD;
oneCount = 0;
}
}
res = (res + (int)(((long)oneCount * (long)(oneCount + 1)) % MOD) / 2) % MOD;
return res;
}
}
提交结果如下:
Python版代码如下:
class Solution:
def numSub(self, s: str) -> int:
oneCount = 0
result = 0
for digit in s:
if digit == '1':
oneCount += 1
else:
result += (oneCount * (oneCount + 1)) // 2
oneCount = 0
result += (oneCount * (oneCount + 1)) // 2
return result % 1000_000_007
提交结果如下: