素心若雪-146号消零专题算法刷题

LeetCode刷题-字符串的最大公因子

2021-07-15  本文已影响0人  小鲨鱼FF

前言说明

算法学习,日常刷题记录。

题目连接

字符串的最大公因子

题目内容

对于字符串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 = "LEET", str2 = "CODE"

输出:""

提示:

1 <= str1.length <= 1000

1 <= str2.length <= 1000

str1[i]和str2[i]为大写英文字母

分析过程

第一步

如果是字符串的最大公因子,肯定是两个字符串str1和str2中短字符串的某个前缀,而且前缀的长度必须同时是两个字符串str1和str2的长度的约数。

第二步

获取字符串str1的长度为length1,获取字符串str2的长度为length2,算出字符串str1和字符串str2的较小长度,然后开始从较小长度遍历到1,从大到小遍历。

第三步

遍历时,判断前缀的长度是否同时是两个字符串str1和str2的长度的约数。

如果不满足,直接跳到下一次遍历。

第四步

如果满足,通过substring的方法获取前缀,定义为str。这里获取前缀str时,用其中的一个字符串切割即可获取到,因为在获取较小长度时,已经限定了前缀str在较小长度的字符串里。

然后调用函数judgeCommon两次,第一次输入前缀str和字符串str1,第二次输入前缀str和字符串str2,如果两次调用都返回true结果,那么字符串str1和字符串str2拥有公因子,公因子就是前缀str。

而前缀str的长度是从大到小遍历的,所以这里一旦找到符合条件的前缀str,前缀str就是最大公因子,即可把前缀str作为返回结果。

第五步

遍历结束后,若不能找到符合条件的前缀str,那么把空字符串作为返回结果。

函数judgeCommon

此函数定义了输入前缀t和字符串s,判断前缀t是否为字符串s的因子。

在函数judgeCommon中,因为字符串s等于多个字符串t相加,即S = T + ... + T(T自身连接1次或多次),所以用字符串s的长度除以字符串t的长度,获取倍数length,即length = s.length() / t.length()。

定义字符串集合sb,遍历倍数length次,每次字符串集合sb添加字符串t。

遍历结束后,若字符串集合sb刚好就等于字符串s,那么表示前缀t能除尽字符串s,即前缀t是字符串s的因子。

解答代码

class Solution {
    public String gcdOfStrings(String str1, String str2) {
        // 思路:答案肯定是某个字符串的前缀,如果要满足最大公因子的条件,前缀的长度必须同时是两个字符串str1和str2的长度的约数

        // 获取字符串str1的长度
        int length1 = str1.length();
        // 获取字符串str2的长度
        int length2 = str2.length();
        
        // 求出字符串str1和字符串str2的较小长度,从较小长度遍历到1,从大到小遍历
        for (int i = Math.min(length1, length2); i >= 1; --i) {
            // 判断前缀的长度是否同时是两个字符串str1和str2的长度的约数
            if (length1 % i == 0 && length2 % i == 0) {
                // 获取前缀,用其中的一个字符串切割即可,因为最大范围已经限定在了较小长度里
                String str = str1.substring(0, i);

                if (judgeCommon(str, str1) && judgeCommon(str, str2)) {
                    // 若前缀和字符串str1、前缀和字符串str2都满足因子关系,那么字符串str1和字符串str2拥有公因子str,因为前缀的长度是从大到小遍历的,所以这里一旦找到符合条件的前缀,即可以返回结果str
                    return str;
                }
            }
        }

        // 若不能找到符合条件的前缀,返回空字符串
        return "";
    }

    // 定义判断是否满足字符串因子的函数
    private boolean judgeCommon(String t, String s) {
        // 因为字符串s等于多个字符串t相加,所以用字符串s的长度除以字符串t的长度,获取倍数length
        int length = s.length() / t.length();

        // 定义字符串集合sb
        StringBuilder sb = new StringBuilder();

        // 遍历倍数length次,每次字符串集合sb添加字符串t
        for (int i = 0; i < length; ++i) {
            sb.append(t);
        }

        // 最后若字符串集合sb刚好就等于字符串s,那么满足字符串t能除尽字符串s,即满足字符串t是字符串s的字符串因子的条件
        return s.equals(sb.toString());
    }
}

提交结果

执行用时1ms,时间击败94.93%的用户,内存消耗38.2MB,空间击败90.13%的用户。

运行结果

原文链接

原文链接:字符串的最大公因子

上一篇下一篇

猜你喜欢

热点阅读