LeetCode.1071-字符串最大公约数(Greatest Common Divisor of Strings)

这是小川的第391次更新,第421篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第253题(顺位题号是1071)。对于字符串ST,当且仅当S = T + ... + TT与自身连接1次或更多次)时,我们说"T除S"

返回最大的字符串X,使得X除以str1X除以str2

例如:

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

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

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

注意

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

02 第一种解法

题目的要求是找出两个字符串str1str2的最大公约数,即str1str2中都存在一个子串,并且都由这个子串重复出现一次或多次组成。

那么,什么情况下这两字符串没有最大公约数?

两者分别前后拼接,但是不相等,那么肯定不存在最大公约数。例如示例中的str1 ="ABCABC"str2 ="ABC"str1拼接str2后变成"ABCABCABC"str2拼接str1后变成"ABCABCABC"。而str1 ="LEET"str2 ="CODE"str1拼接str2后变成"LEETCODE"str2拼接str1后变成"CODELEET",两者显然不相等,肯定不存在公约数。

那怎么找到他们的最大公约数呢?

思路:借助字符串拆分。用不同的子串分别对str1str2进行拆分,通过Stringsplit方法实现,如果拆分后的字符串数组中没剩下任何元素,表明可以被该子串整除。找到两字符串中长度较小的,作为循环次数上限,从后往前依次截取子串,将截取出来的子串用来拆分str1str2,如果拆分后得到的数组长度为0,则此子串就是最大公约数。

public String gcdOfStrings(String str1, String str2) {
    if (!(str1+str2).equals(str2+str1)) {
        return "";
    }
    int n = Math.min(str1.length(), str2.length());
    for (int i=n; i>=1; i--) {
        String temp = str2.substring(0, i);
        if (str2.split(temp).length == 0 &&
                str1.split(temp).length == 0) {
            return temp;
        }
    }
    return "";
}

03 第二种解法

和第一种解法思路类似,依旧是借助字符串的特性,使用替换来验证最大公约数,通过StringreplaceAll方法实现。

public String gcdOfStrings2(String str1, String str2) {
    if (!(str1+str2).equals(str2+str1)) {
        return "";
    }
    int n = Math.min(str1.length(), str2.length());
    for (int i=n; i>=1; i--) {
        if (n%i != 0) {
            continue;
        }
        String temp = str2.substring(0, i);
        if(str1.replaceAll(temp,"").equals("") &&
                str2.replaceAll(temp,"").equals("")) {
            return temp;
        }
    }
    return "";
}

04 第三种解法

我们还可以从数学角度来思考这个问题。

思路:将两个字符串的长度看做求最大公约数的两个整数,单独写一个求两个数最大公约数的算法,算出最大公约数后,取两字符串中长度较小的,截取子串,子串的长度就是前一步算出的最大公约数,该子串也就是我们最后要返回的两字符串的最大公约数。

public String gcdOfStrings3(String str1, String str2) {
    if (!(str1+str2).equals(str2+str1)) {
        return "";
    }
    int len = str1.length();
    int len2 = str2.length();
    int gcd = GCD(len, len2);
    if (len < len2) {
        return str1.substring(0, gcd);
    }
    return str2.substring(0, gcd);
}

public int GCD(int a, int b) {
    if (b == 0) {
        return a;
    }
    return a % b == 0 ? b : GCD(b, a % b);
}

05 第四种解法

我们还可以将第三种解法中用到的求最大公约数的递归方法,和字符串操作整合在一起。

找到两个字符串中长度较大的那个,如果长度大的字符串包含较小长度字符串的所有字符,就用长度较小的字符串对较大中的子串进行替换,直到有一方为空串为止。

public String gcdOfStrings4(String str1, String str2) {
    if (str1.length() < str2.length()) {
        return gcdOfStrings4(str2, str1);
    }
    if (str2.isEmpty()) {
        return str1;
    }
    if (!str1.contains(str2)) {
        return "";
    }
    str1 = str1.replace(str2, "");
    return gcdOfStrings4(str2, str1);
}

06 小结

算法专题目前已连续日更超过七个月,算法题文章259+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

原文地址:https://www.cnblogs.com/xiaochuan94/p/11235674.html

时间: 2024-11-06 13:59:35

LeetCode.1071-字符串最大公约数(Greatest Common Divisor of Strings)的相关文章

【leetcode刷题笔记】Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings. 题解:以strs[0]为模板,每次挨个查看是否所有的串里面是否第i位上都和strs[0]一样,如果都一样,把i位置上的字符放到answer里面,i++,继续循环,否则返回当前的answer. 代码如下: 1 public class Solution { 2 public String longestCommonPrefix

Leetcode中字符串总结

本文是个人对LeetCode中字符串类型题目的总结,纯属个人感悟,若有不妥的地方,欢迎指出. 一.有关数字 1.数转换 题Interger to roman和Roman to integer这两题是罗马数字和整数之间的相互转换,首先要懂得什么是罗马数字以及相应的组数规则.LeetCode的题中给出的数字最大的是3999,.针对第一题有两种解法:第一是列举出罗马数字在个十百千上的各种情况,形成一个二维矩阵,然后对整数不停的取余.除10来确定相应的罗马数字:第二种是先列出罗马数字组成情况,然后通过从

LeetCode:字符串相加【415】

LeetCode:字符串相加[415] 题目描述 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和. 注意: num1 和num2 的长度都小于 5100.num1 和num2 都只包含数字 0-9.num1 和num2 都不包含任何前导零.你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式. 题目分析 这道题其实很简单,我们要搞清楚手工计算两数之和的流程.两数相加,和如果大于10的话就有进位,进位最高为1,默认为0,该位相加的和应为sum%

前端与算法 leetcode 387. 字符串中的第一个唯一字符

目录 # 前端与算法 leetcode 387. 字符串中的第一个唯一字符 题目描述 概要 提示 解析 解法一:双循环 解法二:Set法单循环 算法 传入测试用例的运行结果 执行结果 GitHub仓库 查看更多 # 前端与算法 leetcode 387. 字符串中的第一个唯一字符 题目描述 给定一个字符串,找到它的第一个不重复的字符,并返回它的索引.如果不存在,则返回 -1. 案例: s = "leetcode" 返回 0. s = "loveleetcode",

【LeetCode】LeetCode——第14题:Longest Common Prefix

14. Longest Common Prefix My Submissions Question Editorial Solution Total Accepted: 97052 Total Submissions: 345681 Difficulty: Easy Write a function to find the longest common prefix string amongst an array of strings. Subscribe to see which compan

LeetCode -- 求字符串数组中的最长公共前缀

题目描写叙述: Write a function to find the longest common prefix string amongst an array of strings.就是给定1个字符串数组,找出公共最长前缀. 思路非常直接.使用1个索引来存最长公共前缀的长度就能够了. 注意, 假设使用1个字符串变量来存前缀的话,是不能AC的,由于题目不同意使用额外的空间. public string LongestCommonPrefix(string[] strs) { if(strs

LeetCode之“字符串”:最长回文子串

题目要求: 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串.例如,给出字符串 "abcdzdcab",它的最长回文子串为 "cdzdc". 解答: 这个题目的一个简单的解法就是对字符串中的每一个字符,同时向其两边延展,以找到最长回文子串.这种方法是可以的,但要处理回文子串长度为奇数和偶数的两种情况是比较麻烦的.如下图的几个字符串: “a” "aa" "aaa" "

LeetCode之字符串处理题java

344. Reverse String Write a function that takes a string as input and returns the string reversed. Example: Given s = "hello", return "olleh". Subscribe to see which companies asked this question public class Solution { public String r

【LeetCode】字符串 string(共112题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [3]Longest Substring Without Repeating Characters [5]Longest Palindromic Substring [6]ZigZag Conversion [8]String to Integer (atoi) [10]Regular Expression Matching [12]Integer to Roman