Greatest Common Divisor of Strings
Strings have a divisor iff str1 + str2 == str2 + str1; if so, the answer is the gcd-length prefix.
2 min read
string gcd math
Problem#
Return the largest string that divides both str1 and str2 (a divides b iff repeating it some integer number of times equals b).
Examples#
"ABCABC", "ABC"→"ABC"."ABABAB", "ABAB"→"AB";"LEET", "CODE"→"".
Constraints#
1 <= str1.length, str2.length <= 1000.
Approach#
A common divisor exists iff str1 + str2 == str2 + str1 (both are repetitions of the same root). If so, the root length is gcd(|str1|, |str2|).
Solution#
class Solution {public: string gcdOfStrings(string str1, string str2) { if (str1 + str2 != str2 + str1) return ""; return str1.substr(0, __gcd((int)str1.size(), (int)str2.size())); }};func gcdOfStrings(str1 string, str2 string) string { if str1+str2 != str2+str1 { return "" } gcd := func(a, b int) int { for b != 0 { a, b = b, a%b } return a } return str1[:gcd(len(str1), len(str2))]}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))]function gcdOfStrings(str1, str2) { if (str1 + str2 !== str2 + str1) return ""; const gcd = (a, b) => { while (b !== 0) [a, b] = [b, a % b]; return a; }; return str1.slice(0, gcd(str1.length, str2.length));}class Solution { public String gcdOfStrings(String str1, String str2) { if (!(str1 + str2).equals(str2 + str1)) return ""; return str1.substring(0, gcd(str1.length(), str2.length())); }
private int gcd(int a, int b) { while (b != 0) { int t = a % b; a = b; b = t; } return a; }}function gcdOfStrings(str1: string, str2: string): string { if (str1 + str2 !== str2 + str1) return ""; const gcd = (a: number, b: number): number => { while (b !== 0) [a, b] = [b, a % b]; return a; }; return str1.slice(0, gcd(str1.length, str2.length));}Editorial#
The str1+str2 == str2+str1 test is a clever encoding: two strings commute under concatenation iff they’re powers of a common root. Once we know a common divisor exists, the longest one has length gcd of the two string lengths, mirroring number-theoretic gcd.
Complexity#
- Time:
O(m + n). - Space:
O(m + n).
Concept revision#
Related#