LeetCode The Hard Way
4100 - 4199

4102 - Count Valid Substrings I (Medium)

https://leetcode.com/problems/count-valid-substrings-i/description/

Problem Statement

You are given a string s consisting only of the characters 'a', 'b', and 'c'.

A string is called valid if it does not contain "abc" as a substring.

Return the number of valid substrings in s. Substrings with different starting or ending indices are counted separately.

A substring is a contiguous non-empty sequence of characters within a string.

Example 1:

Input: s = "abac"

Output: 10

Explanation:

The following substrings don't contain "abc"​​​​​​​ as a substring:

  • s[0..0] = "a"
  • s[0..1] = "ab"
  • s[0..2] = "aba"
  • s[0..3] = "abac"​​​​​​​
  • s[1..1] = "b"
  • s[1..2] = "ba"
  • s[1..3] = "bac"
  • s[2..2] = "a"
  • s[2..3] = "ac"
  • s[3..3] = "c"

Thus, the answer is 10.

Example 2:

Input: s = "abc"

Output: 5

Explanation:

The following substrings don't contain "abc"​​​​​​​ as a substring:

  • s[0..0] = "a"
  • s[0..1] = "ab"
  • s[1..1] = "b"
  • s[1..2] = "bc"
  • s[2..2] = "c"​​​​​​​

Thus, the answer is 5.

Example 3:

Input: s = "ac"

Output: 3

Explanation:

All substrings in s don't contain "abc" as a substring​​​​​​​. Thus, the answer is 3.

Constraints:

  • 1 <= s.length <= 1e5
  • s only consists of 'a', 'b', and 'c' characters.

Approach 1: Two Pointers

Fix an ending index ii. If the most recent occurrence of "abc" starts at kk, then every substring ending at ii and starting at or before kk contains that occurrence. Every start after kk avoids it and all earlier occurrences.

Let jj be the earliest valid start, initially 00. Whenever the three characters ending at ii form "abc", its start is i−2i-2, so move jj to i−1i-1. Otherwise, keep jj where it is. The valid starts run from jj through ii inclusive, so add i−j+1i-j+1 to the answer.

The time complexity is O(n)O(n) and the space complexity is O(1)O(1).

Written by@wkw
class Solution:
    def countValidSubstrings(self, s: str) -> int:
        res = j = 0
        for i in range(len(s)):
            if s[i - 2:i + 1] == "abc": j = i - 1
            res += i - j + 1
        return res

On this page