Skip to content
Home » Lintcode 1375 Substring With At Least K Distinct Characters

Lintcode 1375 Substring With At Least K Distinct Characters

Lintcode 1375 Substring With At Least K Distinct Characters

https://www.lintcode.com/problem/1375

Given a string S with only lowercase characters.
Return the number of substrings that contains at least k distinct characters.

Example 1:

Input: S = "abcabcabca", k = 4
Output: 0
Explanation: There are only three distinct characters in the string.

Example 2:

Input: S = "abcabcabcabc", k = 3
Output: 55
Explanation: Any substring whose length is not smaller than 3 contains a, b, c.
    For example, there are 10 substrings whose length are 3, "abc", "bca", "cab" ... "abc"
    There are 9 substrings whose length are 4, "abca", "bcab", "cabc" ... "cabc"
    ...
    There is 1 substring whose length is 12, "abcabcabcabc"
    So the answer is 1 + 2 + ... + 10 = 55.

This problem can also use the two pointers method we talked about in https://leetcode-solution.com/leetcode-209-minimum-size-subarray-sum-2/ with time complexity of O(n)

The idea is the same, iterate the left pointer, at each iteration, find the right pointer so that the subarray has k distinct characters. But there is on tricky part here, once we found a right pointer, all the indices after the right point will also meet the requirement. So instead of increase the final result by 1, we should also consider adding however many indices after the right pointer.

Now let’s take a look at the solution

export class Solution {
  /**
   * @param s: a string
   * @param k: an integer
   * @return: the number of substrings there are that contain at least k distinct characters
   */
  kDistinctCharacters(s, k) {
    let right = 0;
    let result = 0;
    let charToCount = {};
    let distinctCharCount = 0;
    for(let left = 0; left < s.length; left++) {
      while(right < s.length && distinctCharCount < k) {
        if(charToCount[s[right]]) {
          charToCount[s[right]] += 1
        } else {
          charToCount[s[right]] = 1
          distinctCharCount++;
        }
        right++;
      }

      if(distinctCharCount === k) {
        result += s.length - right + 1;
      }

      charToCount[s[left]]--;
      if(charToCount[s[left]] === 0) {
        distinctCharCount--;
      }
    }

    return result;
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *