Repeated String Match

MediumStrings · KMP🧩 String MatchingLeetCode #686 ↗Updated

Problem

Given strings a and b, find the fewest number of times a must be written back-to-back so that b appears inside the result as a contiguous substring. Return -1 if no number of copies works. (Zero copies is the empty string.)
Inputa = "abcd", b = "cdabcdab"Output3 (abcdabcdabcd)
Inputa = "a", b = "aa"Output2
Inputa = "abc", b = "wxyz"Output-1

1 ≤ a.length, b.length ≤ 104  ·  lowercase English letters

Try it yourself

Java
class Solution {
    public int repeatedStringMatch(String a, String b) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
If b occurs at all, it starts within the first copy of a (offset < n). So scanning a text of length n + m is enough, and KMP can walk that text virtually using a.charAt(i % n).
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 ForceAppend and Search Each Time

Time O((m/n + 2) · (n+m) · m)Space O(n + m)

Keep appending a and search for b after every append. Once the built string is at least n + m long without a match, give up: any match must start at an offset < n, so it would already fit.

Java
public int repeatedStringMatch(String a, String b) {
    StringBuilder sb = new StringBuilder();
    int copies = 0;
    while (sb.length() < a.length() + b.length()) {
        sb.append(a);
        copies++;
        if (sb.indexOf(b) >= 0) return copies;
    }
    return -1;
}

Correct and simple, but repeats a full substring search after every copy.

At a glance

LevelApproachTimeSpace
Brute ForceAppend and Search Each TimeO((m/n + 2) · (n+m) · m)O(n + m)
BetterBuild Once, Search OnceO((n+m) · m)O(n + m)
OptimalKMP over a Virtual Repeated TextO(n + m)O(m)
Common pitfalls
  • Stopping at ceil(m/n) copies — an offset start may need one more copy.
  • Looping forever when there is no match — bound the text length by n + m.
  • Off-by-one in ceil: use (x + n - 1) / n with integers.
Interview tips
  • State the bound first: the match must begin inside the first copy of a.
  • Offer the build-and-indexOf version, then upgrade to KMP (or Rabin–Karp) for linear time.
  • Point out the modulo trick avoids allocating the repeated string.
Pattern
String matching on a periodic text → bound the search window, then run KMP over a virtual text.
My notes saved in this browser