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
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%
的用户
*/