错题整理:Leetcode 696 Counting Binary Substrings

205 阅读1分钟

Give a binary string s, return the number of non-empty substrings that have the same number of 0's and 1's, and all the 0's and all the 1's in these substrings are grouped consecutively.

Substrings that occur multiple times are counted the number of times they occur.

刚开始想这道题的时候以为是找所有满足条件的s[i,j], 0<=i<j<len(s), 直接O(n2)O(n^2). 但是这个substring特殊的点在于
对于任何0m1n0^m1^n 的string来说答案是:
min(m,n)min(m,n)
对于任何的0m1n0k0^m1^n0^k来说答案是:
min(m,n)+min(n,k)min(m,n)+min(n,k)
对于任何0a11a10a21a2...0an1an0^{a_1}1^{a_1}0^{a_2}1^{a_2}...0^{a_n}1^{a_n}(也就是任意的binary string, ajN,1jna_j \in \mathbb{N}, 1\leq j \leq n)我们有答案:
min(a1,a2)+min(a2,a3)+min(a3,a4)+...+min(an1,an)min(a_1,a_2)+min(a_2,a_3)+min(a_3,a_4)+...+min(a_{n-1},a_n)
比如对于string "11001011"我们可以分成 12021101121^20^21^10^11^2, 那么所有的满足条件的substring个数为:
min(2,2)+min(2,1)+min(1,1)+min(1,2)=5min(2,2)+min(2,1)+min(1,1)+min(1,2) = 5
用 linear scan 记录 min(a,b)min(a,b) 中的 a 和 b 累加道result即可
Python 代码

    def countBinarySubstrings(self, s: str) -> int:
        res,prev,curr = 0,0,1
        for i in range(1,len(s)):
            if s[i]!= s[i-1]:
                res += min(prev, curr)
                prev = curr
                curr = 1 
            else:
                curr += 1
        return res + min(prev,curr)