Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions problems/0696-count-binary-substrings/analysis.md
Original file line number Diff line number Diff line change
@@ -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.
49 changes: 49 additions & 0 deletions problems/0696-count-binary-substrings/problem.md
Original file line number Diff line number Diff line change
@@ -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'`.
29 changes: 29 additions & 0 deletions problems/0696-count-binary-substrings/solution_daily_20260219.go
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
}