Watch 7 video solutions for Distinct Echo Substrings, a hard level problem involving String, Trie, Rolling Hash. This walkthrough by Pepcoding has 4,001 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Return the number of distinct non-empty substrings of text that can be written as the concatenation of some string with itself (i.e. it can be written as a + a where a is some string).
Example 1:
Input: text = "abcabcabc" Output: 3 Explanation: The 3 substrings are "abcabc", "bcabca" and "cabcab".
Example 2:
Input: text = "leetcodeleetcode" Output: 2 Explanation: The 2 substrings are "ee" and "leetcodeleetcode".
Constraints:
1 <= text.length <= 2000text has only lowercase English letters.Problem Overview: You are given a string and must count how many distinct echo substrings it contains. A substring is an echo substring if it can be written as a + a, meaning the first half is identical to the second half. The task is not just detecting them but counting unique substrings that satisfy this condition.
Approach 1: Sliding Window with Rolling Hash (O(n^2) time, O(n^2) space)
This approach uses a rolling hash to compare substring halves efficiently. Iterate over possible half lengths L. For each starting index i, compute the hash of s[i : i+L] and s[i+L : i+2L]. If the hashes match, the substring s[i : i+2L] is an echo substring. Store its hash in a set to guarantee uniqueness.
The key insight is that hashing reduces substring comparison from O(L) to O(1). Without hashing, each comparison would require character-by-character checks. A prefix-hash array allows constant-time substring hash extraction. Sliding the window across the string for each length produces an overall O(n^2) time complexity. This technique is common in string problems that require fast substring equality checks.
Approach 2: Dynamic Programming with Longest Common Prefix (O(n^2) time, O(n^2) space)
Dynamic programming can precompute the longest common prefix between every pair of indices. Define dp[i][j] as the length of the common prefix starting at positions i and j. Fill the table from the end of the string toward the start. If s[i] == s[j], then dp[i][j] = 1 + dp[i+1][j+1]; otherwise it is zero.
Once the table is built, check pairs of indices where j > i. If dp[i][j] >= j - i, the substring s[i : j] equals s[j : j + (j - i)], forming an echo substring of length 2 * (j - i). Insert the substring into a set to ensure distinct counting. This approach relies on substring matching through precomputed overlaps instead of hashing.
The DP table effectively answers "how many characters match starting from these two positions" in constant time. That makes it easy to verify echo conditions quickly. The tradeoff is memory usage since the n × n matrix can be large.
Recommended for interviews: The rolling hash solution is usually preferred. It demonstrates strong knowledge of substring hashing, prefix hashes, and set-based deduplication. Interviewers often expect candidates to recognize that naive substring comparisons would be too slow and switch to hashing. The DP method shows good understanding of substring relationships but uses more memory. Both approaches rely heavily on concepts from string processing and hashing.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Sliding Window with Rolling Hash | O(n^2) | O(n^2) | Best general solution for large strings; avoids expensive substring comparisons |
| Dynamic Programming (LCP Table) | O(n^2) | O(n^2) | Useful when precomputing substring matches or practicing DP-based string analysis |