Facebook Pixel

3456. Find Special Substring of Length K

EasyString
Leetcode Link

Problem Description

You are given a string s and an integer k.

Determine if there exists a substring of length exactly k in s that satisfies the following conditions:

  1. The substring consists of only one distinct character (e.g., "aaa" or "bbb").
  2. If there is a character immediately before the substring, it must be different from the character in the substring.
  3. If there is a character immediately after the substring, it must also be different from the character in the substring.

Return true if such a substring exists. Otherwise, return false.

Intuition

The problem requires finding consecutive identical characters in the string that form a segment of exact length k, ensuring that the characters before and after this segment differ from it, if they exist.

The solution approach uses the two-pointer technique:

  1. Initialize two pointers, l and r, both starting at the beginning of the string s.
  2. Expand the right pointer r as long as the character at this pointer matches the character at l. This identifies a segment of consecutive identical characters.
  3. Once a different character is found or the end of the string is reached, check if the length of this segment (r - l) is exactly k.
  4. If such a segment is found, return true. Otherwise, reset l to r and continue searching through the string.
  5. If no suitable segment is found by the end of the string, return false.

This approach effectively traverses the string, examining each segment of consecutive identical characters efficiently.

Solution Approach

To solve this problem, the Two Pointers technique is adopted, aiming to efficiently identify segments of consecutive identical characters in the string s of exact length k. Here is the detailed approach:

  1. Initialize a pointer l at the start of the string and calculate the length n of the string s.

  2. Use a loop to increment the pointer l until reaching the end of the string:

    • Within this loop, initialize another pointer r starting from l. Move r to the right as long as s[r] is equal to s[l]. This process identifies a block of consecutive identical characters.

    • Once a character different from s[l] is encountered or the end of the string is reached, check the length of this block: if r - l equals k, it means a valid substring is found, and the function should return True.

  3. If the loop completes without finding any valid substring, return False.

The approach efficiently checks each character only once and correctly identifies segments of exact length k, making it optimal for the given problem constraints. The algorithm can be represented as follows:

class Solution:
    def hasSpecialSubstring(self, s: str, k: int) -> bool:
        l, n = 0, len(s)
        while l < n:
            r = l
            while r < n and s[r] == s[l]:
                r += 1
            if r - l == k:
                return True
            l = r
        return False

This solution leverages the simple yet powerful two-pointer technique, which ensures traversal of the string is efficient, achieving the goal with minimal iterations.

Ready to land your dream job?

Unlock your dream job with a 2-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with an example. Consider the string s = "aabbba" and k = 3.

  1. Initialization:

    • Start with pointers l and r at the beginning of the string (l = 0, r = 0).
    • The length of the string n is 6.
  2. First iteration:

    • l = 0: Character at s[l] is 'a'.
    • Move r to the right as long as s[r] is equal to s[l].
    • The substring from s[0] to s[1] is "aa". Since r becomes 2 and (r - l equals 2), it's not equal to k. So, reset l to r (now both l and r are 2).
  3. Second iteration:

    • l = 2: Character at s[l] is 'b'.
    • Move r to the right as long as s[r] equals s[l].
    • The substring from s[2] to s[4] is "bbb". Here, r becomes 5 and (r - l equals 3). This matches k, and the character immediately before the substring s[1] is 'a', which is different from 'b'. Hence, the conditions are satisfied.
    • Return True.

With this example, the solution evaluates each block of consecutive characters and checks if the conditions are satisfied efficiently using the two-pointer approach.

Solution Implementation

1class Solution:
2    def hasSpecialSubstring(self, s: str, k: int) -> bool:
3        # Initialize two pointers: 
4        # l is the start of the current substring, and r is used to find the end of the same-character substring
5        l, n = 0, len(s)
6      
7        # Iterate over the string until the end
8        while l < n:
9            r = l  # Start the r pointer at the current position of l
10          
11            # Expand r until a different character is found 
12            while r < n and s[r] == s[l]:
13                r += 1
14          
15            # Check the length of the substring of similar consecutive characters
16            if r - l == k:
17                return True  # Return True if the desired length k is found
18          
19            # Move the l pointer to the position of r, to start a new check
20            l = r
21      
22        # Return False if no such substring exists
23        return False
24
1class Solution {
2    public boolean hasSpecialSubstring(String s, int k) {
3        int n = s.length(); // Get the length of the input string.
4      
5        // Traverse the string with two pointers: l (left) and r (right).
6        for (int l = 0; l < n;) {
7            int r = l + 1;
8          
9            // Expand the right pointer while the characters at l and r are the same.
10            while (r < n && s.charAt(r) == s.charAt(l)) {
11                r++;
12            }
13          
14            // Check if the length of the substring of identical characters is equal to k.
15            if (r - l == k) {
16                return true; // Found a substring of exactly k identical characters.
17            }
18          
19            // Move the left pointer to the next new character.
20            l = r;
21        }
22      
23        // If no such substring is found, return false.
24        return false;
25    }
26}
27
1class Solution {
2public:
3    // Function to determine if there is a special substring of length `k` in string `s`
4    bool hasSpecialSubstring(string s, int k) {
5        int n = s.length(); // Length of the string `s`
6      
7        // Loop through the string with `l` as the start of a potential special substring
8        for (int l = 0; l < n;) {
9            int r = l + 1; // Start with `r` as next character after `l`
10          
11            // Move `r` to the right as long as characters at position `r` and `l` are the same
12            while (r < n && s[r] == s[l]) {
13                ++r;
14            }
15          
16            // Check if the length of the substring from `l` to `r` is exactly `k`
17            if (r - l == k) {
18                return true; // Found a special substring, return true
19            }
20          
21            // Move `l` to the position of `r` to check for the next potential substring
22            l = r;
23        }
24      
25        // If no such substring found, return false
26        return false;
27    }
28};
29
1function hasSpecialSubstring(s: string, k: number): boolean {
2    const n = s.length; // Get the length of the input string
3    for (let left = 0; left < n; ) { // Start iterating from the first character
4        let right = left + 1; // Initialize the right pointer for comparison
5        // Extend the right pointer as long as the character at right is equal to the character at left
6        while (right < n && s[right] === s[left]) {
7            right++;
8        }
9        // Check if the length of the substring [left, right) is equal to k
10        if (right - left === k) {
11            return true; // Return true if a valid substring is found
12        }
13        left = right; // Move the left pointer to the position of right for the next iteration
14    }
15    return false; // Return false if no valid substring of length k is found
16}
17

Time and Space Complexity

The time complexity of the code is O(n), where n is the length of the string s. This is because the algorithm makes a single pass through the string, checking consecutive characters and counting their occurrences without revisiting any part of the string.

The space complexity of the code is O(1), as it utilizes a constant amount of extra space for variables l, r, and n, irrespective of the size of the input string.

Learn more about how to find time and space complexity quickly.


Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:
Question 1 out of 10

Which of the two traversal algorithms (BFS and DFS) can be used to find whether two nodes are connected?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!


Load More