leetcode:字符串最大公因子

字符串的最大公因子

对于字符串 st,只有在 s = t + ... + tt 自身连接 1 次或多次)时,我们才认定 “t 能除尽 s”。

给定两个字符串 str1str2 。返回 最长字符串 x,要求满足 x 能除尽 str1x 能除尽 str2

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 1 <= str1.length, str2.length <= 1000
  • str1str2 由大写英文字母组成

O(n2)

class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        res: list = []
        for i in range(len(str2)):
            _str = str2[:i + 1]
            _num1 = len(str1) // len(_str)
            _num2 = len(str2) // len(_str)
            if _num1 * _str == str1 and _num2 * _str == str2:
                if len(str1) % len(_str) == 0 and len(str2) % len(_str) == 0:
                    res.append(_str)
        if not res:
            return ""
        else:
            res = res[-1]
            return "".join(res)

递归版O(n)

class Solution:

    def gcdOfStrings(self, str1: str, str2: str) -> str:
        if str1+str2 != str2+str1:
            return ''
        difference = len(str1)-len(str2)
        
        if difference==0:
            
            return str1

        elif difference > 0:

            str1 = str1[len(str2): len(str1)]

        else:

            str2 = str2[len(str1): len(str2)]

        return self.gcdOfStrings(str1,str2)


优化版O(n)

class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        if not str1 or not str2:
            return str1 if str1 else str2

        if len(str1) < len(str2):
            return self.gcdOfStrings(str2, str1)  # Ensure str1 is not shorter than str2

        if not str1.startswith(str2):
            return ""  # If str1 doesn't start with str2, they don't have a common divisor

        return self.gcdOfStrings(str1[len(str2):], str2)  # Delete the prefix of str1 that equals str2

​ 在这个问题中,我们应当使用欧几里得算法,它常用于计算两个整数的最大公约数,但也可以用于解决这个问题。基本思想是“辗转相除”:如果两个字符串有最大公共因子(GCD),那么整个 str1str2 都应该是由 GCD 重复若干次构成的,这个性质对 str1str2 的任何前缀都应该成立。因此,我们可以不断将较长的字符串替换为其和较短字符串的差,即删除它的前缀,直到两个字符串相等,那么这个字符串就是 GCD,或者其中一个字符串变成空字符串,那么说明它们没有 GCD。

​ 这个实现确保了如果 str1 不以 str2 开头,那么它们没有公共的因子,所以直接返回空字符串。否则,就删除 str1 的前缀 str2,然后递归地寻找 str1[len(str2):]str2 的最大公共因子。最终,如果其中一个字符串变成空字符串,那么另一个字符串就是最大公共因子。

​ 这个实现的时间复杂度是 O(N),其中 N 是 str1str2 的总长度,因为在最坏的情况下,它需要检查 str1str2 的每个字符。空间复杂度也是 O(N),因为 Python 的字符串切片操作会创建新的字符串。这个实现没有使用任何额外的数据结构,所以空间效率较高。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Franda914

有钱的捧个钱场,没钱的点的赞

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值