字符串的最大公因子:
对于字符串 S 和 T,只有在 S = T + ... + T(T 与自身连接 1 次或多次)时,我们才认定 “T 能除尽 S”。
返回最长字符串 X,要求满足 X 能除尽 str1 且 X 能除尽 str2。
示例 1:
输入:str1 = "ABCABC", str2 = "ABC"
输出:"ABC"
示例 2:
输入:str1 = "ABABAB", str2 = "ABAB"
输出:"AB"
示例 3:
输入:str1 = "ABABABAB", str2 = "ABAB"
输出:"ABAB"
示例 4:
输入:str1 = "LEET", str2 = "CODE"
输出:""
提示:
1 <= str1.length <= 1000
1 <= str2.length <= 1000
str1[i] 和 str2[i] 为大写英文字母
自我解答:
呃,自己尝试的方法是双指针,写的又长又臭,调了半天发现题意理解有偏差,写成求字符串最小公因子。。
于是直接看答案了。
力扣题解:
方法一:和求最大公约数一样,可以使用 “辗转相除法”
引用网友的一句话“对不起我不配活在2020我应该活在公元前301年前”。
自己实现的“辗转相除”:
1、可以使用双指针,模拟一个一个找公共字符的过程,如果有不一样的字符,则说明无解,
若一样,记录下公共字符,当某个字符串到达末尾后,结束
2、拿到公共字符串,和剩下的字符串再进行 1 操作,直到str1和str2 都没有剩余字符串了,
得到最大公共字符串。
def gcd_of_strings(str1: str, str2: str) -> str:
str1_len = len(str1)
str2_len = len(str2)
commons = []
i = 0
j = 0
while i < str1_len and j < str2_len:
if str1[i] != str2[j]:
return ""
else:
commons.append(str1[i])
i += 1
j += 1
if i < str1_len:
return gcd_of_strings("".join(commons), str1[i:str1_len])
if j < str2_len:
return gcd_of_strings("".join(commons), str2[j:str2_len])
return "".join(commons)
力扣题解:
1、假设存在这个公共字符串,那么这两个字符串应该存在关系:str1 + str2 == str2 + str1,
可以直接用这个代替"双指针判断是否有不一样的字符"操作,
2、另外,这两个字符串必然是包含关系,在满足1的前提下,更短的那个字符串就是一个公共字符串,
由此,便可以代替双指针记录公共字符串的功能。
3、拿到公共字符串再和剩下的字符串进行 2 操作,直到 2操作中对比的两个字符串相等为止。
def gcd_of_string2(str1: str, str2: str) -> str:
if str1 + str2 != str2 + str1:
return ""
len1, len2 = len(str1), len(str2)
if len1 == len2:
return str1
elif len1 > len2:
return gcd_of_string2(str2, str1[len2:])
else:
return gcd_of_string2(str1, str2[len1:])
还有可特别秀的版本
def gcd_of_string3(str1: str, str2: str) -> str:
import math
return str1[: math.gcd(len(str1), len(str2))] if str1 + str2 == str2 + str1 else ""
原题链接:https://leetcode-cn.com/problems/greatest-common-divisor-of-strings