From 7660eaa4c6b4c8f41d21c0f28f32e02c06a5854a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 03:22:38 +0000 Subject: [PATCH] feat: add solution for 0696. Count Binary Substrings --- .../0696-count-binary-substrings/analysis.md | 52 +++++++++++++++++++ .../0696-count-binary-substrings/problem.md | 49 +++++++++++++++++ .../solution_daily_20260219.go | 29 +++++++++++ .../solution_daily_20260219_test.go | 27 ++++++++++ 4 files changed, 157 insertions(+) create mode 100644 problems/0696-count-binary-substrings/analysis.md create mode 100644 problems/0696-count-binary-substrings/problem.md create mode 100644 problems/0696-count-binary-substrings/solution_daily_20260219.go create mode 100644 problems/0696-count-binary-substrings/solution_daily_20260219_test.go diff --git a/problems/0696-count-binary-substrings/analysis.md b/problems/0696-count-binary-substrings/analysis.md new file mode 100644 index 0000000..2af6d4f --- /dev/null +++ b/problems/0696-count-binary-substrings/analysis.md @@ -0,0 +1,52 @@ +# 0696. Count Binary Substrings + +[LeetCode Link](https://leetcode.com/problems/count-binary-substrings/) + +Difficulty: Easy +Topics: Two Pointers, String +Acceptance Rate: 67.0% + +## Hints + +### Hint 1 + +Think about what makes a valid substring. The 0s and 1s must be grouped — so the structure is always a block of one character followed by a block of the other. What if you focused on the boundaries between groups of consecutive characters? + +### Hint 2 + +Try counting the length of each consecutive group of identical characters. For two adjacent groups (e.g., a block of 0s followed by a block of 1s), how many valid substrings can be formed from just those two groups? + +### Hint 3 + +For any two adjacent groups with lengths `prev` and `curr`, the number of valid substrings spanning that boundary is `min(prev, curr)`. For example, groups "000" and "11" contribute `min(3, 2) = 2` valid substrings: "0011" is not valid (unequal counts), but "01" and "0011" — wait, that's wrong. Actually "01" and "0011" both have equal counts only for "01" (1 each). The valid ones are "01" and "0011"? No: "0011" has 2 zeros and 2 ones, and "01" has 1 each. Both are valid. So from groups of length 3 and 2, we get min(3,2) = 2 substrings. You don't even need to store all the group lengths — just track the previous group's length as you scan. + +## Approach + +The key observation is that every valid substring consists of a block of one character immediately followed by a block of the other character, with equal counts. For example, "0011", "01", "1100", "10" are all valid. + +**Algorithm:** + +1. Scan the string left to right, tracking the length of the current group of consecutive identical characters (`curr`) and the length of the previous group (`prev`). +2. Whenever the character changes (a group boundary), add `min(prev, curr)` to the result. This is because from two adjacent groups of lengths `prev` and `curr`, you can form `min(prev, curr)` valid substrings of varying sizes centered on that boundary. +3. After the transition, set `prev = curr` and reset `curr = 1` to start counting the new group. +4. After the loop ends, add `min(prev, curr)` one final time to account for the last pair of adjacent groups. + +**Walkthrough with "00110011":** + +- Groups: `[00, 11, 00, 11]` → lengths `[2, 2, 2, 2]` +- Between groups 1 and 2: min(2, 2) = 2 → substrings "01", "0011" +- Between groups 2 and 3: min(2, 2) = 2 → substrings "10", "1100" +- Between groups 3 and 4: min(2, 2) = 2 → substrings "01", "0011" +- Total: 6 + +## Complexity Analysis + +Time Complexity: O(n) — single pass through the string. +Space Complexity: O(1) — only two integer variables (`prev` and `curr`) are used. + +## Edge Cases + +- **Single character string** (e.g., "0" or "1"): Only one group exists, no adjacent pair, so the answer is 0. +- **All same characters** (e.g., "0000"): Only one group, answer is 0. +- **Alternating characters** (e.g., "010101"): Every adjacent pair of groups has length 1, so the answer equals `len(s) - 1`. +- **Two groups only** (e.g., "000111"): Answer is min(3, 3) = 3. diff --git a/problems/0696-count-binary-substrings/problem.md b/problems/0696-count-binary-substrings/problem.md new file mode 100644 index 0000000..7b90c30 --- /dev/null +++ b/problems/0696-count-binary-substrings/problem.md @@ -0,0 +1,49 @@ +--- +number: "0696" +frontend_id: "696" +title: "Count Binary Substrings" +slug: "count-binary-substrings" +difficulty: "Easy" +topics: + - "Two Pointers" + - "String" +acceptance_rate: 6699.9 +is_premium: false +created_at: "2026-02-19T03:21:09.147310+00:00" +fetched_at: "2026-02-19T03:21:09.147310+00:00" +link: "https://leetcode.com/problems/count-binary-substrings/" +date: "2026-02-19" +--- + +# 0696. Count Binary Substrings + +Given 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. + + + +**Example 1:** + + + **Input:** s = "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:** s = "10101" + **Output:** 4 + **Explanation:** There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's. + + + + +**Constraints:** + + * `1 <= s.length <= 105` + * `s[i]` is either `'0'` or `'1'`. diff --git a/problems/0696-count-binary-substrings/solution_daily_20260219.go b/problems/0696-count-binary-substrings/solution_daily_20260219.go new file mode 100644 index 0000000..80c1fb2 --- /dev/null +++ b/problems/0696-count-binary-substrings/solution_daily_20260219.go @@ -0,0 +1,29 @@ +package main + +// countBinarySubstrings counts substrings with equal consecutive 0s and 1s. +// Track previous and current group lengths; at each group boundary, +// min(prev, curr) valid substrings exist. O(n) time, O(1) space. +func countBinarySubstrings(s string) int { + prev, curr := 0, 1 + result := 0 + + for i := 1; i < len(s); i++ { + if s[i] == s[i-1] { + curr++ + } else { + result += min(prev, curr) + prev = curr + curr = 1 + } + } + result += min(prev, curr) + + return result +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/problems/0696-count-binary-substrings/solution_daily_20260219_test.go b/problems/0696-count-binary-substrings/solution_daily_20260219_test.go new file mode 100644 index 0000000..ce2bc6b --- /dev/null +++ b/problems/0696-count-binary-substrings/solution_daily_20260219_test.go @@ -0,0 +1,27 @@ +package main + +import "testing" + +func TestCountBinarySubstrings(t *testing.T) { + tests := []struct { + name string + input string + expected int + }{ + {"example 1: grouped pairs", "00110011", 6}, + {"example 2: alternating", "10101", 4}, + {"edge case: single character", "0", 0}, + {"edge case: all same characters", "1111", 0}, + {"edge case: two different characters", "01", 1}, + {"edge case: two groups equal length", "000111", 3}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := countBinarySubstrings(tt.input) + if result != tt.expected { + t.Errorf("countBinarySubstrings(%q) = %d, want %d", tt.input, result, tt.expected) + } + }) + } +}