一、題目
給定一個字符串 s
,計算具有相同數量0和1的非空(連續)子字符串的數量,並且這些子字符串中的所有0和所有1都是組合在一起的。
重複出現的子串要計算它們出現的次數。
示例 1 :
輸入: "00110011" 輸出: 6 解釋: 有6個子串具有相同數量的連續1和0:“0011”,“01”,“1100”,“10”,“0011” 和 “01”。 請注意,一些重複出現的子串要計算它們出現的次數。 另外,“00110011”不是有效的子串,因爲所有的0(和1)沒有組合在一起。
示例 2 :
輸入: "10101" 輸出: 4 解釋: 有4個子串:“10”,“01”,“10”,“01”,它們具有相同數量的連續1和0。
注意:
s.length
在1到50,000之間。s
只包含“0”或“1”字符。
二、題解思路
- 題解思路1:多次遍歷字符串,第一次遍歷,看子字符串長度爲2的情況,是否存在這樣的子字符串;第二次遍歷,看子字符串長度爲4的情況.....;........,發現這樣計算嚴重超時(不可取,說明有時候暴力破解是不行的)。
- 題解思路2:參考別人的想法,遍歷字符串,將遍歷過程中出現相同數字的個數存入數組,然後遍歷數組,相鄰兩個值取最小的值,疊加求和即爲滿足要求的子串的個數、例如:1100100:數組中存的長度爲2、2、1、2,相鄰兩個取最小:min(2,2)=2 (因爲對於1100來說存在兩種滿足要求的連續子串:10、1100)、min(2,1)=1,min(1,2)=1.故滿足要求的子串總和爲2+1+1=4,輸出爲4。
- 題解思路3:用last來記錄之前一種字符的個數,cur來記錄當前字符的個數,當last>=cur時,滿足條件的子串計數變量自動加一。
三、代碼實現
- C++代碼實現題解思路1
class Solution {
public:
int countBinarySubstrings(string s)
{
int counts = 0;
int size_1 = s.size();
int counts1 = 2;
while(counts1 <= size_1)
{
int i = 0;
while(i+counts1-1<size_1)
{
string temp = s.substr(i,counts1); //從i位置開始,截取counts1個字符
int flag = 0;
for(int j = 0;j<counts1/2;j++)
{
if(temp[j] == temp[counts1-j]) //說明不是所有0和所有1都是組合在一起的
flag = 1;
}
if(flag == 0) //是所有0和所有1組合在一起,flag標誌位沒變,則獲得一個滿足要求的子串
counts++;
i++;
}
counts1 = counts1 +2;
}
return counts;
}
};
- C++代碼實現題解思路2
class Solution {
public:
int countBinarySubstrings(string s)
{
vector<int> nums;
int counts = 1;
for(int i =0;i<s.size()-1;i++) //將0或1連出現的次數依次記下來
{
if(s[i] == s[i+1])
{
counts++;
if(i+1 == s.size()-1 && s[i+1] == s[i]) //最後一個字符和倒數第二個字符一樣
nums.push_back(counts);
}
else
{
nums.push_back(counts);
counts = 1;
}
}
if(counts == 1) //如果最後一個字符不是和倒數第二個一樣,則需要往數組中再存入一個1
nums.push_back(1);
int count_sum = 0;
for(int i = 0;i<nums.size()-1;i++)
{
count_sum += min(nums[i],nums[i+1]); //取相鄰兩個字符的最小值疊加入總和
}
return count_sum;
}
};
- C++代碼實現題解思路3
class Solution {
public:
int countBinarySubstrings(string s)
{
int last = 0; //前一種字符的個數變量
int cur = 1; //當前字符的個數變量
int count = 0; //滿足要求的子串個數
for(int i = 1;i<s.size();i++) //對於s長度爲1的情況,直接不滿足,然後直接不執行for循環
{
if(s[i]==s[i-1]) //當前的字符與前一個字符一樣
{
cur++; //當前字符個數加1
}
else
{
last = cur; //將當前字符個數賦給last
cur = 1;
}
if(last >= cur)
count++;
}
return count;
}
};