1071. Greatest Common Divisor of Strings
leetcode easy
#csharp#easy#leetcode#math#prefix-sum#string#tree
Task
Для двух строк s и t мы говорим, что "t делит s", если и только если s = t + t + t + ... + t (т.е. t соединена сама с собой один или более раз).
Даны две строки str1 и str2, верните наибольшую строку x, такую что x делит и str1, и str2.
Пример:
Input: str1 = "ABCABC", str2 = "ABC"
Output: "ABC"
C# solution
matched/originalpublic class Solution {
public bool Valid(string str1, string str2, int k) {
int len1 = str1.Length, len2 = str2.Length;
if (len1 % k > 0 || len2 % k > 0) {
return false;
} else {
string baseStr = str1.Substring(0, k);
int n1 = len1 / k, n2 = len2 / k;
return str1 == JoinWords(baseStr, n1) && str2 == JoinWords(baseStr, n2);
}
}
public string JoinWords(string str, int k) {
var sb = new StringBuilder();
for (int i = 0; i < k; i++) {
sb.Append(str);
}
return sb.ToString();
}
public string GcdOfStrings(string str1, string str2) {
int len1 = str1.Length, len2 = str2.Length;
for (int i = Math.Min(len1, len2); i >= 1; i--) {
if (Valid(str1, str2, i)) {
return str1.Substring(0, i);
}
}
return "";
}
}C++ solution
auto-draft, review before submit#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
public bool Valid(string str1, string str2, int k) {
int len1 = str1.size(), len2 = str2.size();
if (len1 % k > 0 || len2 % k > 0) {
return false;
} else {
string baseStr = str1.Substring(0, k);
int n1 = len1 / k, n2 = len2 / k;
return str1 == JoinWords(baseStr, n1) && str2 == JoinWords(baseStr, n2);
}
}
public string JoinWords(string str, int k) {
var sb = new StringBuilder();
for (int i = 0; i < k; i++) {
sb.Append(str);
}
return sb.ToString();
}
public string GcdOfStrings(string str1, string str2) {
int len1 = str1.size(), len2 = str2.size();
for (int i = min(len1, len2); i >= 1; i--) {
if (Valid(str1, str2, i)) {
return str1.Substring(0, i);
}
}
return "";
}
}Java solution
matched/originalclass Solution {
fun valid(str1: String, str2: String, k: Int): Boolean {
val len1 = str1.length
val len2 = str2.length
if (len1 % k > 0 || len2 % k > 0) {
return false
} else {
val base = str1.substring(0, k)
val n1 = len1 / k
val n2 = len2 / k
return str1 == base.repeat(n1) && str2 == base.repeat(n2)
}
}
fun gcdOfStrings(str1: String, str2: String): String {
val len1 = str1.length
val len2 = str2.length
for (i in minOf(len1, len2) downTo 1) {
if (valid(str1, str2, i)) {
return str1.substring(0, i)
}
}
return ""
}
}JavaScript solution
matched/originalclass Solution {
valid(str1, str2, k) {
let len1 = str1.length, len2 = str2.length;
if (len1 % k > 0 || len2 % k > 0) {
return false;
} else {
let base = str1.slice(0, k);
let n1 = Math.floor(len1 / k), n2 = Math.floor(len2 / k);
return str1 === this.joinWords(base, n1) && str2 === this.joinWords(base, n2);
}
}
joinWords(str, k) {
let ans = '';
for (let i = 0; i < k; ++i) {
ans += str;
}
return ans;
}
gcdOfStrings(str1, str2) {
let len1 = str1.length, len2 = str2.length;
for (let i = Math.min(len1, len2); i >= 1; --i) {
if (this.valid(str1, str2, i)) {
return str1.slice(0, i);
}
}
return "";
}
}Python solution
matched/originalclass Solution:
def valid(self, str1, str2, k):
len1, len2 = len(str1), len(str2)
if len1 % k > 0 or len2 % k > 0:
return False
else:
base = str1[:k]
n1, n2 = len1 // k, len2 // k
return str1 == base * n1 and str2 == base * n2
def gcdOfStrings(self, str1, str2):
len1, len2 = len(str1), len(str2)
for i in range(min(len1, len2), 0, -1):
if self.valid(str1, str2, i):
return str1[:i]
return ""Go solution
matched/originalfunc valid(str1, str2 string, k int) bool {
len1, len2 := len(str1), len(str2)
if len1 % k > 0 || len2 % k > 0 {
return false
} else {
base := str1[:k]
n1, n2 := len1 / k, len2 / k
return str1 == joinWords(base, n1) && str2 == joinWords(base, n2)
}
}
func joinWords(str string, k int) string {
ans := ""
for i := 0; i < k; i++ {
ans += str
}
return ans
}
func gcdOfStrings(str1, str2 string) string {
len1, len2 := len(str1), len(str2)
for i := min(len1, len2); i >= 1; i-- {
if valid(str1, str2, i) {
return str1[:i]
}
}
return ""
}
func min(a, b int) int {
if a < b {
return a
}
return b
}Explanation
Algorithm
1⃣Найдите более короткую строку среди str1 и str2, для простоты пусть это будет str1.
2⃣Начните с base = str1 и проверьте, состоят ли обе строки str1 и str2 из множителей строки base. Если это так, верните base. В противном случае, попробуйте более короткую строку, удалив последний символ из base.
3⃣Если вы проверили все префиксные строки и не нашли строку GCD, верните "".
😎