Quick Overview

A string algorithms problem: given a lowercase string of up to 30,000 characters, return the longest substring that occurs at least twice, where occurrences may overlap and ties go to the lexicographically smallest substring. It tests efficient repeated-substring search on long inputs, where a quadratic scan is too slow.

Longest Substring That Occurs at Least Twice, Overlaps Allowed

Company: Google

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

Given a string `s`, find the longest substring that occurs in `s` at least twice. The occurrences may overlap. Return that substring, or the empty string when no substring occurs twice. ### Function Signature ```python def longest_repeated_substring(s: str) -> str: ``` ### Rules - A substring is a contiguous, non-empty block of characters of `s`. - A substring is repeated when it occurs at two or more different starting positions in `s`. Occurrences may overlap: in `"aaaa"`, the substring `"aaa"` occurs at positions `0` and `1`. - Return the longest repeated substring. If several different repeated substrings share the maximum length, return the lexicographically smallest of them (ordinary character-by-character string order). - Return `""` when no substring is repeated, that is, when all characters of `s` are different. ### Constraints - `1 <= len(s) <= 3 * 10^4` - `s` consists only of lowercase English letters `a` to `z`. ### Examples **Example 1** ```text Input: s = "banana" Output: "ana" ``` `"ana"` occurs at positions `1` and `3`; the two occurrences share the middle `"a"`. No substring of length 4 occurs twice. **Example 2** ```text Input: s = "cdcdabab" Output: "ab" ``` `"cd"` and `"ab"` each occur twice, and no substring of length 3 occurs twice. `"ab"` is lexicographically smaller than `"cd"`. **Example 3** ```text Input: s = "abcd" Output: "" ``` Every character occurs once, so no substring is repeated.

Overview: A string algorithms problem: given a lowercase string of up to 30,000 characters, return the longest substring that occurs at least twice, where occurrences may overlap and ties go to the lexicographically smallest substring. It tests efficient repeated-substring search on long inputs, where a quadratic scan is too slow.

Given a string `s`, find the longest substring that occurs in `s` at least twice and return it. Occurrences may overlap. Return the empty string when no substring occurs twice. Implement `longest_repeated_substring(s)`, which returns that substring. ### Rules - A substring is a contiguous, non-empty block of characters of `s`. - A substring is repeated when it occurs at two or more different starting positions in `s`. Occurrences may overlap: in `"aaaa"`, the substring `"aaa"` occurs at positions `0` and `1`. - Return the longest repeated substring. If several different repeated substrings share the maximum length, return the lexicographically smallest of them (ordinary character-by-character string order). - Return `""` when no substring is repeated, that is, when all characters of `s` are different. ### Examples **Example 1** ```text Input: s = "banana" Output: "ana" ``` `"ana"` occurs at positions `1` and `3`; the two occurrences share the middle `"a"`. No substring of length 4 occurs twice. **Example 2** ```text Input: s = "cdcdabab" Output: "ab" ``` `"cd"` and `"ab"` each occur twice, and no substring of length 3 occurs twice. `"ab"` is lexicographically smaller than `"cd"`, so it is returned even though `"cd"` appears first. ### Constraints - `1 <= len(s) <= 3 * 10^4` - `s` consists only of lowercase English letters `a` to `z`. The return value is always a substring of `s` or the empty string; no integer crosses the function boundary, so no value can exceed 2^31 - 1.

Constraints

  • 1 <= len(s) <= 3 * 10^4
  • s consists only of lowercase English letters 'a' to 'z'.

Examples

Input: ('a',)

Expected Output: ''

Explanation: Minimum length 1: a single character cannot occur twice, so the answer is empty.

Input: ('aa',)

Expected Output: 'a'

Explanation: Smallest input with a repeat: 'a' occurs at positions 0 and 1, while 'aa' occurs once.

Hints

  1. Occurrences may overlap: in a string made of one repeated letter, the longest repeated substring is only one character shorter than the whole string.
  2. If a substring of length L occurs at two different positions, then every shorter piece cut from the same two starting positions also occurs twice, so the achievable repeat lengths have no gaps.
  3. With up to 3 * 10^4 characters, comparing every pair of starting positions character by character is far too slow; aim for close to n log n work, and apply the smallest-string tie-break only among candidates of the maximum length.

Loading coding console...

Show the approach

Approach

Build the suffix array of s by prefix doubling. Invariant: after the round that uses step k, each suffix carries a rank equal to the order of its first 2k characters among all suffixes, where a suffix that ends early sorts before any longer continuation (the -1 / 0 sentinel). Each round sorts by the pair (rank of the first k characters, rank of the next k characters), and rounds stop as soon as all n ranks are distinct, which happens by the time 2k >= n because distinct suffixes differ within their first n characters. Kasai's algorithm then fills lcp[r], the length of the longest common prefix of the suffixes at sorted positions r - 1 and r, in O(n) total: moving from text position i to i + 1 lowers the matched length by at most one. Correctness: a substring T is repeated exactly when it is a common prefix of two suffixes that start at different positions, which is what makes overlapping occurrences count automatically. Two suffixes sharing a prefix of length L stay within a contiguous block of the sorted order, so some adjacent pair also shares it; hence the maximum lcp value L is the answer's length. Prefixes of length L never decrease along the sorted order, so the first sorted position r with lcp[r] = L gives the lexicographically smallest repeated substring of that length, s[sa[r] : sa[r] + L], wherever it first occurs in s. Edge cases: a string of length 1, or any string whose characters are all different, has every lcp equal to 0 and returns the empty string; a single repeated letter returns n - 1 copies of it.

Time complexity:
O(n log^2 n)
Space complexity:
O(n)