题目描述

[EN | CN]

对于字符串 S 和 T,只有在 S = T + ... + TT 与自身连接 1 次或多次)时,我们才认定 “T 能除尽 S”。

返回最长字符串 X,要求满足 X 能除尽 str1 且 X 能除尽 str2

示例 1:

1
2
输入:str1 = "ABCABC", str2 = "ABC"
输出:"ABC"

示例 2:

1
2
输入:str1 = "ABABAB", str2 = "ABAB"
输出:"AB"

示例 3:

1
2
输入:str1 = "LEET", str2 = "CODE"
输出:""

提示:

  • 1 <= str1.length <= 1000
  • 1 <= str2.length <= 1000
  • str1[i] 和 str2[i] 为大写英文字母。

解法 1:暴力法

简单遍历所有的可能的 XX 应该满足以下条件:

  • X 的长度能整除两个字符串的长度。
  • X 是两个字符串的前缀。
  • X 重复到两个字符串的长度时候能够等于这两个字符串。

复杂度分析略。

实现与结果如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        len1, len2 = len(str1), len(str2)
        for i in range(min(len1, len2), 0, -1):
            if (len1 % i == 0 and
                len2 % i == 0 and
                str1[:i] * (len1 // i) == str1 and
                str1[:i] * (len2 // i) == str2):
                return str1[:i]
        return ''
  • 执行用时:40 ms,在所有 Python3 提交中击败了 66.73% 的用户。
  • 内存消耗:13.5 MB,在所有 Python3 提交中击败了 14.29% 的用户。

解法 2:最大公约数

仔细思考,如果一个字符串 X 能够经过若干次重复分别得到这两个数,那么 X 的长度一定是这两个数的公约数。题目中要求我们求最大 X,那么它的长度只有可能是这两个数的最大公约数。所以我们只需要验证这个数即可。

实现与结果如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from math import gcd
class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        len_x = gcd(len(str1), len(str2))
        x = str1[:len_x]
        if (x * (len(str1) // len_x) == str1 and
            x * (len(str2) // len_x) == str2):
            return x
        else:
            return ''
  • 执行用时:36 ms,在所有 Python3 提交中击败了 83.58% 的用户。
  • 内存消耗:13.6 MB,在所有 Python3 提交中击败了 14.29% 的用户。