leetcode(84)

leetcode(84),第1张

leetcode(84) 字符串的最大公因子

题目描述:
对于字符串 S 和 T,只有在 S = T + … + T(T 自身连接 1 次或多次)时,我们才认定 “T 能除尽 S”。
返回最长字符串 X,要求满足 X 能除尽 str1 且 X 能除尽 str2。
示例 :
输入:str1 = “ABCABC”, str2 = “ABC”
输出:“ABC”
提示:

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

长度从大到小逐个判断是否是两个字符串的子串。

代码
class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        for i in range(min(len(str1), len(str2)), 0, -1):
            if self.func(str1[0: i], str1) and self.func(str1[0: i], str2):
                return str1[0: i]
        return ""
    
    def func(self, str1, str2):  # 判断 str1 是否为 str2 的子串
        if len(str2) % len(str1):
            return False
        n1, n2 = len(str1), len(str2)
        for i in range(n2 // n1):
            if str1 != str2[i*n1: (i+1)*n1]:
                return False
        return True
      
测试结果

执行用时:48 ms, 在所有 Python3 提交中击败了 8.09% 的用户
内存消耗:15 MB, 在所有 Python3 提交中击败了 28.31% 的用户

解法二

注:我们这里的子串并非寻常意义的子串,而是可以除尽的子串。
首先公共子串的长度必然是两个字符串长度的公约数。我们假设最大公约数为 m,另一个不同的公约数为 n,那么两个字符串的长度都是 m 和 n 的倍数,即都是 m 和 n 的公倍数,所以 m 和 n 的最小公倍数 k 也是两个字符串长度的公约数,所以 k >= m;又因为 m 是最大公约数,所以 m >= k,所以 m = k。这意味着 m 必然是 n 的倍数,所以如果长度为 n 的子串满足都是两个字符串的子串,那么长度为 m 的子串也会满足都是两个字符串的子串。所以我们只需要把最大公约数给求出来,判断是否为两个字符串的子串,如果是,那么它一定是最长的;如果不是,那就意味着其他公约数长度的子串也不会满足需求,即不存在这样的子串。

代码
class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        gcd = math.gcd(len(str1), len(str2))
        if str1 + str2 == str2 + str1:
            return str1[0: gcd]
        return ""
    
      
测试结果

执行用时:36 ms, 在所有 Python3 提交中击败了 40.07% 的用户
内存消耗:15 MB, 在所有 Python3 提交中击败了 65.07% 的用户

说明

算法题来源:力扣(LeetCode)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/3972857.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-21
下一篇 2022-10-21

发表评论

登录后才能评论

评论列表(0条)

保存