❓696. 计数二进制子串
难度:简单
给定一个字符串 s
,统计并返回具有相同数量 0
和 1
的非空(连续)子字符串的数量,并且这些子字符串中的所有 0
和所有 1
都是成组连续的。
重复出现(不同位置)的子串也要统计它们出现的次数。
示例 1:
输入:s = “00110011”
输出:6
解释:6 个子串满足具有相同数量的连续 1 和 0 :“0011”、“01”、“1100”、“10”、“0011” 和 “01” 。
注意,一些重复出现的子串(不同位置)要统计它们出现的次数。
另外,“00110011” 不是有效的子串,因为所有的 0(还有 1 )没有组合在一起。
示例 1:示例 2:
输入:s = “10101”
输出:4
解释:有 4 个子串:“10”、“01”、“10”、“01” ,具有相同数量的连续 1 和 0 。
提示:
- 1 < = s . l e n g t h < = 1 0 5 1 <= s.length <= 10^5 1<=s.length<=105
s[i]
为'0'
或'1'
💡思路:
法一:中心扩展法
- 从字符串的某一位置为中心,尝试着在两边扩展子字符串。
和 647. 回文子串 类似。
法二:
由于要求子字符串中的所有 0
和所有 1
都是成组连续的,所以只需统计字符串 s
中相对 0
或 1
连续出现的个数,然后只需比较相邻的连续0
和1
:
从左往右遍历数组 s
,记录和当前位置数字相同且连续的长度cur
,以及其之前连续的不同数字的 长度pre
:
- 如果当前字符和前一个字符相等,则
cur++
; - 如果不相等,则取
pre
和cur
的最小值,此最小值,就是可以拼成满足条件的字串个数。- 例如
111001
,当遍历到最后一个1
时,于前面的0
不同,则比较pre
和cur
,此时的pre = 3 (最前面的连续的3个1)
、cur = 2 (中间的连续的2个0)
; - 取最小值,即有两个满足条件的字串,分别为:
10
和1100
。
- 例如
🍁代码:(Java、C++)
Java
class Solution {
public int countBinarySubstrings(String s) {
int cnt = 0;
for(int i = 0; i < s.length() - 1; i++){
if(s.charAt(i) != s.charAt(i + 1)){
cnt++;
int l = i - 1, r = i + 2;
while(l >= 0 && r < s.length() && s.charAt(l) == s.charAt(l + 1) &&s.charAt(r) == s.charAt(r - 1)){
cnt++;
l--;
r++;
}
}
}
return cnt;
}
}
C++
class Solution {
public:
int countBinarySubstrings(string s) {
int cnt = 0;
for(int i = 0; i < s.size() - 1; i++){
if(s[i] != s[i + 1]){
cnt++;
int l = i - 1, r = i + 2;
while(l >= 0 && r < s.size() && s[l] == s[l + 1] && s[r] == s[r - 1]){
cnt++;
l--;
r++;
}
}
}
return cnt;
}
};
法二:
Java
class Solution {
public int countBinarySubstrings(String s) {
int cnt = 0;
int pre = 0, cur = 1;
for(int i = 1; i < s.length(); i++){
if(s.charAt(i) == s.charAt(i - 1)) cur++;
else{
cnt += Math.min(pre, cur);
pre = cur;
cur = 1;
}
}
cnt += Math.min(pre, cur);
return cnt;
}
}
C++
class Solution {
public:
int countBinarySubstrings(string s) {
int cnt = 0;
int pre = 0, cur = 1;
for(int i = 1; i < s.size(); i++){
if(s[i] == s[i - 1]) cur++;
else{
cnt += min(pre, cur);
pre = cur;
cur = 1;
}
}
cnt += min(pre, cur);
return cnt;
}
};
🚀 运行结果:
🕔 复杂度分析:
- 时间复杂度:
O
(
n
)
O(n)
O(n),其中
n
为字符串s
的长度;而中心扩展法为 O ( n 2 ) O(n^2) O(n2)。 - 空间复杂度: O ( 1 ) O(1) O(1)。
题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我 leetCode专栏,每日更新!