-- 字符串 - mid 点击直达力扣
给你一个二进制字符串 s(仅由 '0' 和 '1' 组成的字符串)。
返回所有字符都为 1 的子字符串的数目。
由于答案可能很大,请你将它对 10^9 + 7 取模后返回。
示例 1:
输入:s = "0110111"
输出:9
解释:共有 9 个子字符串仅由 '1' 组成
"1" -> 5 次
"11" -> 3 次
"111" -> 1 次
/*
解题思路:
1、对字符串以0为分界线进行切割,得到新数组
2、遍历新数组,求取数组中的每一项的所有可能集合的值
3、使用map存储结果,若map中已有值,直接返回,避免重复计算
*/
function numSub(s: string): number {
let sum = 0
let map = {}
// 按0进行分割,截取有效的连续1的集合
let newS = s.split("0").filter(num => num != '')
// 遍历数组中的每一项,并累积求和
for (let str of newS) {
sum += getNumber(str.length, map)
}
return sum % 1000000007
};
// 查找连续长度为 n 的 1 的集合,字符都为 1 的子字符串的数目
function getNumber(len: number, map: object): number {
// 若map中有数据,则不用再计算直接返回结果
if (map[len]) { return map[len] }
let num = 0
// eg:1111: 1 出现4次; 11 出现3次; 111 出现2次; 1111 出现1次。
for (let i = 0; i < len; i++) { num += len - i }
// 将结果存储到map中
map[len] = num
return num
}