TL;DR
The answer is the prefix of length gcd(len1, len2) β and it exists iff str1 + str2 == str2 + str1. O(m + n) time, O(m + n) space.
Approach 1 β Brute force (try every candidate length)
Any dividing string is a prefix of str1, so scan candidate lengths from the shortest string down to 1. For each length, take that prefix and verify it tiles both strings exactly.
class Solution:
def gcdOfStrings(self, str1: str, str2: str) -> str:
def divides(base: str, s: str) -> bool:
if len(s) % len(base) != 0:
return False
return base * (len(s) // len(base)) == s
shorter = min(len(str1), len(str2))
for length in range(shorter, 0, -1):
cand = str1[:length]
if divides(cand, str1) and divides(cand, str2):
return cand
return ""
Complexity: O(min(m, n)) candidate lengths, each verified in O(m + n) β O(min(m, n) Β· (m + n)) time. For 1000-char inputs that is fine, but it does far more work than needed.
Approach 2 β GCD of lengths + commutativity test
The insight: if a common base string x exists, then both str1 and str2 are made of copies of x, so gluing them in either order produces the same run of xβs β meaning str1 + str2 == str2 + str1. Conversely, if that equality fails, no common base can exist. And when it holds, the longest base has length gcd(len(str1), len(str2)), because the base length must divide both lengths and we want the largest such divisor.
from math import gcd
class Solution:
def gcdOfStrings(self, str1: str, str2: str) -> str:
if str1 + str2 != str2 + str1:
return ""
return str1[:gcd(len(str1), len(str2))]
gcd here is Euclidβs algorithm on the two lengths (not the strings): it repeatedly replaces the larger number by its remainder mod the smaller until one hits zero.
Walkthrough with str1 = "ABCABC", str2 = "ABC":
- Commutativity:
"ABCABC" + "ABC" = "ABCABCABC" and "ABC" + "ABCABC" = "ABCABCABC" β equal, so a common divisor exists.
gcd(6, 3) = 3, so the answer is str1[:3] = "ABC".
For str1 = "ABABAB", str2 = "ABAB": gcd(6, 4) = 2, and the strings commute, so the answer is "AB" β correctly rejecting the longer common prefix "ABAB".
Complexity: O(m + n) time (the concatenations dominate; the gcd is O(log) on the lengths), O(m + n) space for the concatenated strings.
Common pitfalls
- Returning the full
gcd-length prefix without the commutativity check β a shared prefix does not guarantee a shared tiling (e.g. "AABA" and "AA").
- Taking
gcd of the string contents instead of the two lengths.
- Forgetting that an empty answer
"" is a valid return when no common base exists.
Pattern takeaway
When one object is built by repeating another, questions about their βcommon unitβ often reduce to number theory on their sizes: the common tiling length is the gcd of the individual lengths. A concatenation-commutativity check (a + b == b + a) is the clean existence test for βboth are powers of one string.β