Give a string s
, count the number of non-empty (contiguous) 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.
Example 1:
Input: "00110011" Output: 6 Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01".
Notice that some of these substrings repeat and are counted the number of times they occur.
Also, "00110011" is not a valid substring because all the 0's (and 1's) are not grouped together.
Example 2:
Input: "10101" Output: 4 Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.
Note:
s.length
will be between 1 and 50,000.
s
will only consist of "0" or "1" characters.
这一题就是给你一个字符串,问你有几个子串01数量相等。请注意,就是相同数字不能隔开,比如1010两个1和两个0都不在一起所以不行。
解题思路:
我们可以把一个字符串分组,来记录数字出现了多少次。 比如 00111 我们可以分成groups=[2,3], 11110可以分成groups=[4,1].
这样当最后计数的时候,对每一个值取min(groups[i-1], groups[i])
.。
这是为什么呢? 试想groups=[2,3]的情况,要么是00111要么是11000,无论是哪一种情况都只有 0011 、01或是1100、10两个子串符合条件,也就是groups中相邻两数的最小值。
代码如下:
class Solution(object):
def countBinarySubstrings(self, s):
groups = [1]
for i in xrange(1, len(s)):
if s[i-1] != s[i]:
groups.append(1)
else:
groups[-1] += 1
ans = 0
for i in xrange(1, len(groups)):
ans += min(groups[i-1], groups[i])
return ans
还有我瞎写的一个暴力解法,思路就是找出每个数与它之后的几个数相等,重复次数记为count。再往后找不一样的数,看个数与count是否相等。如果相等说明符合条件。
:
class Solution(object):
def countBinarySubstrings(self, s):
"""
:type s: str
:rtype: int
"""
self.flag=0
self.count=1
self.res=0
for i in range(len(s)):
self.flag = 0
self.count = 1
j=i
while(j+1=len(s)): self.flag=1
while(k
这个解法亲测是没问题的,但是在leetcode上会报超时,时间复杂度比较高。