美文网首页素心若雪-146号消零专题算法刷题
LeetCode刷题-字符串的最大公因子

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

作者: 小鲨鱼FF | 来源:发表于2021-07-15 07:26 被阅读0次

    前言说明

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

    题目连接

    字符串的最大公因子

    题目内容

    对于字符串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%的用户。

    运行结果

    原文链接

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

    相关文章

      网友评论

        本文标题:LeetCode刷题-字符串的最大公因子

        本文链接:https://www.haomeiwen.com/subject/pqqupltx.html