|
| 1 | +package com.fishercoder.solutions; |
| 2 | + |
| 3 | +/** |
| 4 | + * 1071. Greatest Common Divisor of Strings |
| 5 | + * |
| 6 | + * For strings S and T, we say "T divides S" if and only if S = T + ... + T (T concatenated with itself 1 or more times) |
| 7 | + * Return the largest string X such that X divides str1 and X divides str2. |
| 8 | + * |
| 9 | + * Example 1: |
| 10 | + * Input: str1 = "ABCABC", str2 = "ABC" |
| 11 | + * Output: "ABC" |
| 12 | + * |
| 13 | + * Example 2: |
| 14 | + * Input: str1 = "ABABAB", str2 = "ABAB" |
| 15 | + * Output: "AB" |
| 16 | + * |
| 17 | + * Example 3: |
| 18 | + * Input: str1 = "LEET", str2 = "CODE" |
| 19 | + * Output: "" |
| 20 | + * |
| 21 | + * Note: |
| 22 | + * |
| 23 | + * 1 <= str1.length <= 1000 |
| 24 | + * 1 <= str2.length <= 1000 |
| 25 | + * str1[i] and str2[i] are English uppercase letters. |
| 26 | + * */ |
| 27 | +public class _1071 { |
| 28 | + public static class Solution1 { |
| 29 | + public String gcdOfStrings(String str1, String str2) { |
| 30 | + if (str1.isEmpty() || str2.isEmpty()) { |
| 31 | + return ""; |
| 32 | + } |
| 33 | + String commomDivisor = str2; |
| 34 | + while (commomDivisor != null && !commomDivisor.isEmpty()) { |
| 35 | + if (isDivisor(str1, commomDivisor)) { |
| 36 | + return commomDivisor; |
| 37 | + } else { |
| 38 | + commomDivisor = findNextShorterCommonDivisor(str2, commomDivisor); |
| 39 | + } |
| 40 | + } |
| 41 | + return ""; |
| 42 | + } |
| 43 | + |
| 44 | + private String findNextShorterCommonDivisor(String str2, String commomDivisor) { |
| 45 | + int length = nextPossibleLength(str2, commomDivisor.length() - 1); |
| 46 | + while (length > 1) { |
| 47 | + if (isDivisor(str2, length)) { |
| 48 | + return str2.substring(0, length); |
| 49 | + } |
| 50 | + length = nextPossibleLength(str2, length - 1); |
| 51 | + } |
| 52 | + return null; |
| 53 | + } |
| 54 | + |
| 55 | + private boolean isDivisor(String str2, int length) { |
| 56 | + String commonDivisorCandidate = str2.substring(0, length); |
| 57 | + for (int i = 0; i < str2.length() - length; i += length) { |
| 58 | + if (!str2.substring(i, i + length).equals(commonDivisorCandidate)) { |
| 59 | + return false; |
| 60 | + } |
| 61 | + } |
| 62 | + return true; |
| 63 | + } |
| 64 | + |
| 65 | + private int nextPossibleLength(String str2, int bound) { |
| 66 | + if (bound <= 0) { |
| 67 | + return -1; |
| 68 | + } |
| 69 | + int len = bound; |
| 70 | + while (str2.length() % len != 0) { |
| 71 | + len--; |
| 72 | + } |
| 73 | + return len; |
| 74 | + } |
| 75 | + |
| 76 | + private boolean isDivisor(String str1, String commomDivisor) { |
| 77 | + if (str1.length() == commomDivisor.length()) { |
| 78 | + return str1.equals(commomDivisor); |
| 79 | + } |
| 80 | + int i = 0; |
| 81 | + for (; i < str1.length() - commomDivisor.length(); i += commomDivisor.length()) { |
| 82 | + if (!str1.substring(i, i + commomDivisor.length()).equals(commomDivisor)) { |
| 83 | + return false; |
| 84 | + } |
| 85 | + } |
| 86 | + return i == (str1.length() - commomDivisor.length()); |
| 87 | + } |
| 88 | + |
| 89 | + } |
| 90 | +} |
0 commit comments