【LeetCode】696. 計數二進位制子串
阿新 • • 發佈:2020-08-10
題目連結
題目描述
給定一個字串 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”字元。
解題思路
我們可以將字串 s 按照 0 和 1的連續段分組,存在counts 陣列中,例如 s = 00111011可以得到這樣的counts 陣列:{counts} = {2, 3, 1, 2};counts陣列中的兩個相鄰的數一定代表著兩種不同的資料,經過觀法可以發現,兩種不同資料組成的滿足條件的子串數目=min(a,b);
例如00111,counts = {2,3},能組成的滿足條件的子串數目=min(2,3) = 2,經過驗證確實為2
AC程式碼
解法一:
兩次遍歷,空間複雜度時間複雜度都為O(n)
class Solution { public int countBinarySubstrings(String s) { ArrayList<Integer> ls = new ArrayList<Integer>(); int num = 1; for(int i = 1; i < s.length(); i++){ if(s.charAt(i) == s.charAt(i-1)) num++; else{ ls.add(num); num = 1; } } ls.add(num); int ans = 0; for(int i = 1; i < ls.size(); i++){ ans += Math.min(ls.get(i),ls.get(i-1)); } return ans; } }
解法二:
解法二是對解法一的優化,理解了解法一,解法二就非常容易理解了,
一次遍歷,空間複雜度O(1),時間複雜度O(n)
class Solution { public int countBinarySubstrings(String s) { int num = 1; int anoth = 0; int ans = 0; for(int i = 1; i < s.length(); i++){ if(s.charAt(i) == s.charAt(i-1)){ num++; }else{ ans += Math.min(num,anoth); anoth = num; num = 1; } } ans += Math.min(num,anoth); return ans; } }