Longest Duplicate Substring

HardBinary Search · Rolling Hash (Rabin–Karp)🧩 String MatchingLeetCode #1044 ↗Updated

Problem

Given a string s, return any substring that occurs at least twice (occurrences may overlap) and is as long as possible. If no substring repeats, return the empty string.
Inputs = "banana"Output"ana"
Inputs = "abcd"Output""
Inputs = "aaaa"Output"aaa"

2 ≤ s.length ≤ 3 · 104  ·  lowercase English letters  ·  any valid longest answer is accepted

Try it yourself

Java
class Solution {
    public String longestDupSubstring(String s) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Repetition is monotone in length: if some length-L substring repeats, so does its length-(L−1) prefix. Binary search on L, and test each L in O(n) by sliding a rolling hash over all windows.
PatternString Matching

Instinct Find a pattern in a text, or a prefix that is also a suffix, faster than O(n·m) - reach for the KMP prefix function or a rolling hash.

Memory hack KMP remembers borders, Rabin-Karp compares fingerprints - neither one re-reads text it has already seen.

Open the String Matching guide →

Approaches

Brute ForceEvery Length, Longest First

Time O(n3)Space O(n2)

For L = n-1 down to 1, put every length-L substring in a hash set; the first collision is a repeat of the largest possible length, so return it immediately.

Java
public String longestDupSubstring(String s) {
    int n = s.length();
    for (int len = n - 1; len > 0; len--) {
        Set<String> seen = new HashSet<>();
        for (int i = 0; i + len <= n; i++) {
            String sub = s.substring(i, i + len);
            if (!seen.add(sub)) return sub;
        }
    }
    return "";
}

Straightforward, but up to n lengths × n substrings × O(L) hashing each.

At a glance

LevelApproachTimeSpace
Brute ForceEvery Length, Longest FirstO(n3)O(n2)
BetterBinary Search on Length + HashSet of SubstringsO(n2 log n)O(n2)
OptimalBinary Search + Rabin–Karp Rolling HashO(n log n) expectedO(n)
Common pitfalls
  • Linear search over L from long to short with hashing — O(n2), times out.
  • Trusting a single hash without verification — collisions give wrong answers.
  • Negative values when removing the outgoing char — add the modulus before %.
Interview tips
  • Spot the monotone predicate first; it justifies binary search on the answer.
  • Explain the rolling update formula and the role of BL.
  • Mention the suffix array + LCP solution as the deterministic O(n log n) alternative.
Pattern
Binary search on answer + Rabin–Karp → find the longest length L for which some window-of-length-L property holds.
My notes saved in this browser