Taro Logo

Largest Substring Between Two Equal Characters

Easy
1 views
2 months ago

Given a string s, return the length of the longest substring between two equal characters, excluding the two characters. If there is no such substring return -1.

A substring is a contiguous sequence of characters within a string.

For example:

  • If s = "aa", the output should be 0. The optimal substring here is an empty substring between the two 'a's.
  • If s = "abca", the output should be 2. The optimal substring here is "bc".
  • If s = "cbzxy", the output should be -1. There are no characters that appear twice in s.

Write a function to solve this problem efficiently.

Sample Answer
def longest_substring_between_equal_characters(s: str) -> int:
    """Given a string s, return the length of the longest substring between two equal characters, excluding the two characters. If there is no such substring return -1."""
    max_length = -1
    for i in range(len(s)):
        for j in range(i + 1, len(s)):
            if s[i] == s[j]:
                max_length = max(max_length, j - i - 1)
    return max_length


# Example usage
print(longest_substring_between_equal_characters("aa"))  # Output: 0
print(longest_substring_between_equal_characters("abca"))  # Output: 2
print(longest_substring_between_equal_characters("cbzxy")) # Output: -1

Naive Approach

The provided code implements a straightforward, brute-force approach:

  1. Nested Loops: It iterates through all possible pairs of characters in the string using nested loops.
  2. Equality Check: For each pair, it checks if the characters are equal.
  3. Length Calculation: If equal characters are found, it calculates the length of the substring between them and updates the max_length if the current substring is longer.

Optimal Solution

The provided solution is already relatively optimal for the constraints given (string length <= 300). A hash map or dictionary could be used to store the first occurrence of each character to avoid the inner loop, but given the input size, the performance difference would likely be negligible.

def longest_substring_between_equal_characters_optimal(s: str) -> int:
    """Given a string s, return the length of the longest substring between two equal characters, excluding the two characters. If there is no such substring return -1."""
    first_occurrence = {}
    max_length = -1
    for i, char in enumerate(s):
        if char in first_occurrence:
            max_length = max(max_length, i - first_occurrence[char] - 1)
        else:
            first_occurrence[char] = i
    return max_length

Big(O) Run-Time Analysis - Naive

The naive approach has a time complexity of O(n^2), where n is the length of the string s. This is because of the nested loops, which iterate through all possible pairs of characters in the string. For each pair, a comparison is made, resulting in a quadratic time complexity.

Big(O) Space Usage Analysis - Naive

The space complexity of the naive approach is O(1) because it uses a constant amount of extra space, regardless of the input string size. Only a single variable max_length is used to track the maximum length found so far.

Big(O) Run-Time Analysis - Optimal

The optimal approach has a time complexity of O(n), where n is the length of the string s. This is because it iterates through the string only once. For each character, it performs a constant-time operation to check if the character is in the hash map and update the max_length if necessary.

Big(O) Space Usage Analysis - Optimal

The space complexity of the optimal approach is O(1). Since the problem states that s contains only lowercase English letters, the first_occurrence dictionary will store at most 26 characters, making it a constant space usage regardless of the input string size. If the character set was unbounded, then the space complexity would be O(min(n, alphabet_size)).

Edge Cases:

  1. Empty String: The problem statement specifies that the string length is between 1 and 300, so we don't need to handle an empty string.
  2. String with One Character: If the string has only one character (e.g., "a"), the loops won't execute, and the function will return -1, which is correct.
  3. String with No Repeating Characters: If there are no repeating characters (e.g., "abcdef"), the max_length will remain -1, which is the expected output.
  4. String with All Same Characters: If all characters are the same (e.g., "aaaaaa"), the function will correctly calculate the length of the substring between the first and last characters, excluding the characters themselves.
  5. Long String: For long strings with repeating characters spread far apart, the algorithm correctly identifies the longest substring between them.