str1
, str2
: 입력되는 2개의 문자열 ()
2개의 문자열 s
, t
가 있을 때, s
은 여러 개의 t
로 나눠질 수 있다. (t가 1개 일수도 더 많을 수도 있다)
이 때, str1
, str2
가 주어졌을 때 str1
, str2
둘다를 나눌 수 있는 가장 긴 x
를 찾는 문제이다.
x
는 str1
, str2
를 모두 나눌 수 있는 문자열이라는 것은 x
를 반복하면 str1
, str2
모두 만들 수 있다는 의미이다.
따라서 이 두 문자열 길이에 x
길이를 나누었을 때 나누어 떨어져야 하므로 두 문자열 길이의 최대 공약수가 될 수 있는 x
의 최대 길이라 할 수 있다.
최대 공약수의 길이를 구하고 str1
의 첫번째 인덱스부터 최대공약수 길이만큼 슬라이싱하고,
이 슬라이싱한 문자열을 반복했을 때 str1
, str2
모두를 만들어낼 수 있는지 확인해서 결과값을 반환하면 될 것이다.
나누어 떨어지는지 확인하는 함수 →
최대공약수 계산 →
최종 시간복잡도
최악의 경우 이므로 충분히 동작할 수 있다.
str1
, str2
의 공통 문자열 중에 가장 긴 것을 찾으면 된다고 생각한 것이다.import math
class Solution:
def gcdOfStrings(self, str1: str, str2: str) -> str:
# s가 t를 반복해 만들어지는지 확인하는 함수
def divides(s, t):
# 나누어 떨어지지 않으면 t 반복해서 만들기 불가능
if len(s) % len(t) != 0:
return False
# t를 s길이에서 t길이를 나눈 몫만큼 반복한 문자열이 s면 True, 아님 False
return s == t * (len(s) // len(t))
# 문자열 길이의 최대공약수 구하기
gcd_len = math.gcd(len(str1), len(str2))
# str1 중 길이가 최대공약수인 부분을 후보 설정
candidate = str1[:gcd_len]
# 반복해서 만들 수 있는지 확인
if divides(str1, candidate) and divides(str2, candidate):
# 되면 최대공약수 문자열 맞음
return candidate
else:
# 아니면 빈 문자열
return ""
class Solution:
def gcdOfStrings(self, str1: str, str2: str) -> str:
# 두 문자열 길이 저장
len1, len2 = len(str1), len(str2)
# 후보 길이 l이 str1, str2 길이를 모두 나누는지 확인
def isdivisor(l):
# 나누어 떨어지지 않으면 후보 문자열 불가능
if(len1 % l or len2 % l):
return False
# 나누어 떨어지면 몇번 반복되는지 계산
f1,f2 = len1//l, len2//l
# str1에서 l길이 만큼만 접근한 값에 각각의 몫을 곱해서 두 문자열이 만들어지는지 확인
return str1[:l] * f1 == str1 and str1[:l] * f2 == str2
# 후보 길이를 l부터 0까지 역방향 탐색 = 길이 긴 것부터 확인
for i in range(min(len1,len2),0,-1):
# 후보가 두 문자열 모두 잘 나누면 해당 문자열 반환
if(isdivisor(i)):
return str1[:i]
# 조건 맞는 후보 없으면 빈 문자열 반환
return ""