✔️ Sliding Window | Python | C++ | Java | JS | C# | Go | Rust | Swift | Kotlin
IntuitionWe need to count all substrings that contain at least one occurrence of 'a', 'b', and 'c'. My first thought was to use a sliding window approach, as it
# Intuition
We need to count all substrings that contain at least one occurrence of `'a'`, `'b'`, and `'c'`. My first thought was to use a **sliding window** approach, as it's well-suited for finding substrings with specific character constraints.

# Approach
The key insight is using a sliding window with two pointers (`left` and `right`) to efficiently find all valid substrings:
  1. Maintain a sliding window and a **hash map** (dictionary) to count occurrences of `'a'`, `'b'`, and `'c'`.
  2. Expand the window by moving the `right` pointer and incrementing the count of the character at that position.
  3. When the window contains at least one of each required character, we have a valid window.
  4. For each valid window from `[left, right]`, all substrings that start at position `left` and end at or after position `right` will also be valid. There are `len(s) - right` such substrings.
  5. Contract the window from the `left` by incrementing the `left `pointer and decrementing the character count, until the window is no longer valid.
  6. Repeat this process until the `right` pointer reaches the end of the string. 

# Complexity
- Time complexity: O(n)
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: O(1)
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```python3 []
class Solution:
    def numberOfSubstrings(self, s: str) -> int:
        count = 0
        left = 0
        char_count = {'a': 0, 'b': 0, 'c': 0}
        
        for right in range(len(s)):
            char_count[s[right]] += 1
            
            while char_count['a'] > 0 and char_count['b'] > 0 and char_count['c'] > 0:
                count += len(s) - right
                char_count[s[left]] -= 1
                left += 1
        
        return count
```
```cpp []
class Solution {
public:
    int numberOfSubstrings(string s) {
        int count = 0;
        int left = 0;
        unordered_map<char, int> char_count = {{'a', 0}, {'b', 0}, {'c', 0}};
        
        for (int right = 0; right < s.length(); ++right) {
            char_count[s[right]]++;
            
            while (char_count['a'] > 0 && char_count['b'] > 0 && char_count['c'] > 0) {
                count += s.length() - right;
                char_count[s[left]]--;
                left++;
            }
        }
        
        return count;
    }
};
```
```java []
class Solution {
    public int numberOfSubstrings(String s) {
        int count = 0;
        int left = 0;
        int[] charCount = new int[3];

        for (int right = 0; right < s.length(); right++) {
            charCount[s.charAt(right) - 'a']++;

            while (charCount[0] > 0 && charCount[1] > 0 && charCount[2] > 0) {
                count += s.length() - right;
                charCount[s.charAt(left) - 'a']--;
                left++;
            }
        }

        return count;
    }
}
```
```javascript []
var numberOfSubstrings = function(s) {
    let count = 0;
    let left = 0;
    let charCount = { 'a': 0, 'b': 0, 'c': 0 };

    for (let right = 0; right < s.length; right++) {
        charCount[s[right]]++;

        while (charCount['a'] > 0 && charCount['b'] > 0 && charCount['c'] > 0) {
            count += s.length - right;
            charCount[s[left]]--;
            left++;
        }
    }

    return count;
};
```
```csharp []
public class Solution {
    public int NumberOfSubstrings(string s) {
        int count = 0;
        int left = 0;
        Dictionary<char, int> charCount = new() {
            { 'a', 0 }, { 'b', 0 }, { 'c', 0 }
        };

        for (int right = 0; right < s.Length; right++) {
            charCount[s[right]]++;

            while (charCount['a'] > 0 && charCount['b'] > 0 && charCount['c'] > 0) {
                count += s.Length - right;
                charCount[s[left]]--;
                left++;
            }
        }

        return count;
    }
}
```
```go []
func numberOfSubstrings(s string) int {
    count := [3]int{}
    result, left := 0, 0

    for right, char := range s {
        count[char-'a']++

        for count[0] > 0 && count[1] > 0 && count[2] > 0 {
            result += len(s) - right
            count[s[left]-'a']--
            left++
        }
    }

    return result
}
```
```rust []
impl Solution {
    pub fn number_of_substrings(s: String) -> i32 {
        let mut count = [0; 3];
        let mut result = 0;
        let mut left = 0;

        for (right, c) in s.chars().enumerate() {
            count[(c as u8 - b'a') as usize] += 1;

            while count[0] > 0 && count[1] > 0 && count[2] > 0 {
                result += (s.len() - right) as i32;
                count[(s.as_bytes()[left] - b'a') as usize] -= 1;
                left += 1;
            }
        }

        result
    }
}
```
```swift []
class Solution {
    func numberOfSubstrings(_ s: String) -> Int {
        var count: [Character: Int] = ["a": 0, "b": 0, "c": 0]
        var result = 0
        var left = 0
        let chars = Array(s)

        for right in 0..<chars.count {
            count[chars[right], default: 0] += 1

            while count["a", default: 0] > 0 && count["b", default: 0] > 0 && count["c", default: 0] > 0 {
                result += s.count - right
                count[chars[left], default: 0] -= 1
                left += 1
            }
        }

        return result
    }
}
```
```kotlin []
class Solution {
    fun numberOfSubstrings(s: String): Int {
        val count = mutableMapOf('a' to 0, 'b' to 0, 'c' to 0)
        var result = 0
        var left = 0

        for (right in s.indices) {
            count[s[right]] = count.getOrDefault(s[right], 0) + 1

            while (count['a']!! > 0 && count['b']!! > 0 && count['c']!! > 0) {
                result += s.length - right
                count[s[left]] = count[s[left]]!! - 1
                left++
            }
        }

        return result
    }
}
```

---

![upvote.png](https://assets.leetcode.com/users/images/79cec92c-bcfb-43ac-a723-651f5f8501ba_1741669759.5859208.png)

['Hash Table', 'Swift', 'C++', 'Java', 'Go', 'Python3', 'Rust', 'Kotlin', 'JavaScript', 'C#']