lc0502

✅ 1071. 字符串的最大公因子

https://leetcode-cn.com/problems/greatest-common-divisor-of-strings/

描述

对于字符串 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"
输出:""

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/greatest-common-divisor-of-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解答

sum:

  • java and c using gcd
  • py 那边是用:最长替换子 来干

why we can use gcd

51949DBA-4AB6-45CC-A984-AA932C8C45BF.png

Java ans; watch inside, and u see comments:

class Solution {
    public String gcdOfStrings(String str1, String str2) {
        /*
        如果 str1 和 str2 存在最大公约数 str,那么就相当于 str1 和 str2 都是由 str 组成的,那么 str1 + str2 和 str2 + str1 应该是相等的
        如果不满足,那么不存在最大公约数

        我们可以通过 两个字符串的长度来求得最大公约数的长度
        比如 str1 = "ABABAB", str2 = "ABAB"
            len1 = 6         len2 = 4
            那么最大公约数 str = "AB"
                         len = 2
        */
        // java 里面有个 string + 的重载,这挺好
        if(!(str1 + str2).equals(str2 + str1)){
            return "";
        }

        return str2.substring(0, gcd(str1.length(), str2.length()));
    }
    /*              a   b
                    18  12
    18 % 12 = 6     12  6
    12 % 6  = 0     6   0
    */
    private int gcd(int a, int b){
        //保证 a 比 b 大,不加这个也没问题,下一次递归会自动变成 a > b
        if(a < b){
            return gcd(b, a);
        }
        if(a % b == 0){
            return b;
        }else{
            return gcd(b, a % b);
        }
    }
}

c

/*
最大公因子串的长度sublen一定是str1和str2的长度的最大公因数,
我这么说你明白没有,
采用假设性原则,假设存在这个子串,
所以先不急,计算一手两串长度len1,len2,再接求出len1,len2的最大公因数,
记为最大公因子串的长度sublen,把假设的substr的值赋值为str1的前sublen个元素,
有人说,你怎么知道这个子串一定存在呢,
这个时候先不慌,将substr依次和str1,str2比对,
如果出现匹配不上的字符,崩,撤,卖,溜!直接返回空串,
如果全匹配完的话,ok,直接起飞,最后返回substr,*/
int gcd(int a,int b)
{
   // printf("%d %d\n",a,b);
    if(0==b)
    {
        return a;
    }
    else
    {
        return gcd(b,a%b);
    }
}

char * gcdOfStrings(char * str1, char * str2){
    int len1=0,len2=0;
    while(*(str1+len1)!=0)
    {
        len1++;
    }
    while(*(str2+len2)!=0)
    {
        len2++;
    }
    int sublen=gcd(len1,len2);
    char *substr;
    substr=(char*)malloc((sublen+1)*sizeof(char));
    *(substr+sublen)='\0';
    for(int i=0;i<sublen;i++)
    {
        *(substr+i)=*(str1+i);
    }
    // now check if there is any mismatch char in substr and str1 (and str2 tt2)
    for(int i=0;i<len1;i++)
    {
        if(*(str1+i)!=*(substr+(i%sublen)))
        {
            *substr='\0';
            return substr;
        }
    }
    //tt2
    for(int i=0;i<len2;i++)
    {
        if(*(str2+i)!=*(substr+(i%sublen)))
        {
            *substr='\0';
            return substr;
        }
    }
    return substr;
}

py

class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        if not str1 or not str2:
            return ''
        length1,length2 = len(str1),len(str2)
        # make sure that str1 is shorter one
        if length1 > length2:
            str1,str2 = str2,str1
        # from len(str1) backward: like 9,8,7...0(yes: till 0)
        for i in range(len(str1)-1,-1,-1):
            s = str1[:i+1]
            # 如果所有的s作为一个替换子,可以把str1 and str2 替换到 空字符串,那么就是立刻返回 这个s 替换子。
            if not str1.replace(s,''):
                if not str2.replace(s,''):
                    return s
            '''
            tt: if not '' === True;; conclusion is: '' === False;
            '''
        return ''

循环的gcd 怎么写的?cnm

int c = 0;
// n > m(其实不搞这个,第二步也会自动 n m 交换,然后满足: n > m;
void gcd(int n, int m) {
    while(m != 0) {
        c = n % m;
        n = m;
        m = c;
    }
    return n;
}

my c

int gcd(int a, int b){
    if(b == 0) {
        return a;
    } else {
        return gcd(b, a%b);
    }
    // loop:
    /*
    int c = 0;
    while (b != 0) {
        c = a / b;
        a = b;
        b = c;
    }
    return a;*/
}

char * gcdOfStrings(char * str1, char * str2){
    //char tmp1[1001], tmp2[1001];
// this code is wrong when input is 360 ge AAA....(360+), cause notice ur tt2: strcat, it may overflow the the tmpx arr boundary;

    char tmp1[2001], tmp2[2001];

    memset(tmp1, '\0', sizeof(tmp1));
    memset(tmp2, '\0', sizeof(tmp2));
    strcpy(tmp1, str1);
    strcpy(tmp2, str2);
    if(strcmp(strcat(tmp1, str2), strcat(tmp2, str1)) != 0) {
        // they are not the same;
        return "";
    }
    // they are the same;
    int i, j, k;
    i = strlen(str1);
    j = strlen(str2);
    k = gcd(i, j);
    char *ret;
    ret = (char *) malloc(1001);
    memset(ret,'\0',1001);//oh man, you must use: \0; not use jst 0; !!!!!!!!!!!!!!!!!!!!!tt8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    strncpy(ret, str1, k);
    return ret;
}
/*
执行用时 :
0 ms
, 在所有 C 提交中击败了
100.00%
的用户
内存消耗 :
5.6 MB
, 在所有 C 提交中击败了
100.00%
的用户

*/

posted on 2020-05-02 19:58  Paulkg12  阅读(429)  评论(0编辑  收藏  举报

导航