仅含 1 的子串数

仅含 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

提示:

  • s[i] == ‘0’ 或 s[i] == ‘1’
  • 1 <= s.length <= 10^5

分析及代码

  • 先分析连续的1

    例如: 1111
    * 4个1
    * 3个11
    * 2个111
    * 一个1111
    * 一共4+3+2+1=(4+1)*4/2

  • 总结
    对于n个连续的1,符合要求的有:(n+1)*n/2
    对于不连续的1,可以把它当做几个连续的1的片段,再把片段加起来

  • 代码1:
    那么,直接遍历,用一个变量记录连续1的个数
    如果遇到非零的数,则sum=sum+(n+1)*n/2
class Solution {
public:int numSub(string s) {int num=0,sum=0;for(int i=0;i<s.size();i++){if(s[i]=='1'){num++;}else{sum = sum+(num+1)*num/2;num=0;}}return sum;}
};

在这里插入图片描述

问题
没有考虑到11011011的情况

  • 代码2
class Solution {
public:int numSub(string s) {int num=0,sum=0;for(int i=0;i<s.size();i++){if(s[i]=='1'){num++;if(i+1==s.size()){sum = sum+(num+1)*num/2;}}else{sum = sum+(num+1)*num/2;num=0;}}return sum;}
};

在这里插入图片描述

数组溢出问题

  • 代码3
class Solution {
public:int numSub(string s) {long long num=0,sum=0;for(int i=0;i<s.size();i++){if(s[i]=='1'){num++;if(i+1==s.size()){sum = sum+(num+1)*num/2;}}else{sum = sum+(num+1)*num/2;num=0;}}return sum;}
};

在这里插入图片描述

  • 代码4:
class Solution {
public:static constexpr int P = int(1E9) + 7;int numSub(string s) {int p = 0;long long ans = 0;while (p < s.size()) {if (s[p] == '0') {++p;continue;}int cnt = 0;while (p < s.size() && s[p] == '1') {++cnt;++p;}ans = ans + (1LL + (long long)cnt) * cnt / 2;ans = ans % P;}return ans;}
};


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部