[Leetcode] 0696. 计数二进制子串

696. 计数二进制子串

点击上方链接跳转至leetcode

题目描述

给定一个字符串 s,统计并返回具有相同数量 01 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的。

重复出现(不同位置)的子串也要统计它们出现的次数。

 

示例 1:

输入:s = "00110011"
输出:6
解释:6 个子串满足具有相同数量的连续 1 和 0 :"0011"、"01"、"1100"、"10"、"0011" 和 "01" 。
注意,一些重复出现的子串(不同位置)要统计它们出现的次数。
另外,"00110011" 不是有效的子串,因为所有的 0(还有 1 )没有组合在一起。

示例 2:

输入:s = "10101"
输出:4
解释:有 4 个子串:"10"、"01"、"10"、"01" ,具有相同数量的连续 1 和 0 。

 

提示:

  • 1 <= s.length <= 105
  • s[i]'0''1'

解法

我们可以将字符串 ss 按照 00 和 11 的连续段分组,存在counts数组中,例如 s = 00111011,可以得到这样的 counts 数组: counts={2,3,1,2}。
这里counts数组中两个相邻的数一定代表的是两种不同的字符。假设counts数组中两个相邻的数字为u或者v,它们对应着u个00 和 v 个 11,或者u 个 11 和v 个 00。它们能组成的满足条件的子串数目为min{u,v},即一对相邻的数字对答案的贡献。
我们只要遍历所有相邻的数对,求它们的贡献总和,即可得到答案。

Python3

from typing import List    

class Solution:
    def countBinarySubstrings(self, s: str) -> int:
        i, n = 0, len(s)
        t = []
        while i < n:
            cnt = 1
            while i + 1 < n and s[i + 1] == s[i]:
                cnt += 1
                i += 1
            t.append(cnt)
            i += 1
        ans = 0
        for i in range(1, len(t)):
            ans += min(t[i - 1], t[i])
        return ans


fun = Solution()
s = "00110011"
res = fun.countBinarySubstrings(s)
print(res)

C++

#include<iostream>
#include<string>
#include<vector>
using namespace std;

class Solution{
public:
    int countBinarySubstrings(string s) {
        int i =0,n = s.size();
        vector<int> t;
        while(i<n){
            int cnt = 1;
            while(i+1 < n && s[i+1] == s[i]){
                ++cnt;
                ++i;
            }
            t.push_back(cnt);
            ++i;
        }
        int ans = 0;
        for(i =1;i<t.size();++i)
            ans += min(t[i-1],t[i]);
        return ans;
    }
};

int main(){

    string s= "00110011";
    int res = Solution().countBinarySubstrings(s);
    cout << "res: " << res << endl;

    return  0;
}

//g++ 696.cpp -std=c++11

复杂度分析:

时间复杂度和空间复杂度都是O(n)。

作者:野哥李
微信公众号:AI算法学习社
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
本文章不做任何商业用途,仅作为自学所用,文章后面会有参考链接,我可能会复制原作者的话,如果介意,我会修改或者删除。

posted @   野哥李  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-05-05 Python 列表定义
点击右上角即可分享
微信分享提示

目录导航