2、字符串的最大公因子

原题力扣《字符串的最大公因子》
难度:简单
题目:对于字符串 s 和 t,只有在 s = t + t + t + … + t + t(t 自身连接 1 次或多次)时,我们才认定 “t 能除尽 s”。
给定两个字符串 str1 和 str2,返回 最长字符串 x,要求满足 x 能除尽 str1 且 x 能除尽 str2 。

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 1 <= str1.length, str2.length <= 1000
  • str1 和 str2 由大写英文字母组成

解题:JS
个人:硬解

  1. 除尽指的是 str = n * x => str / x = n(整数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @param {string} str1
* @param {string} str2
* @return {string}
*/
var gcdOfStrings = function (str1, str2) {
let base = ''

let i = 0;

while (i < str1.length || i < str2.length) {
base += str1.slice(0, i)
if (str1.split(base).join('') || str2.split(base).join('')) {
i++
}
}

return base
};

没解出来
解题耗时:16 min

官方:最大公约数、辗轧相除法
约数:相除后余数为零,就可以称为约数,4 % 2 = 0,则 2 是 4 的约数
思路 1:

  1. 这个思路是没问题的:除尽指的是 str = n * x => str / x = n(整数),那表明存在某个字符串 x
  2. 那一定存在这个逻辑:str1.length % x.length === str2.length % x.length === 0
  3. 并且为了取得最大公约数,就需要从最长的开始循环往下找
  4. 题目简化为:求 4、6 的最大公约数,x 从 6 开始递减,若 4、6 都除尽 x,则找到 x 了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 判断字符串 str 是否除尽字符串 x
var checkString = function (x, str) {
// 通过 JS 的 replaceAll 来判断
return str.replaceAll(x, "") === "";
};

var gcdOfStrings = function (str1, str2) {
const len1 = str1.length;
const len2 = str2.length;

let x = ''

let maxstr = len1 > len2 ? str1 : str2;

for (let maxlen = maxstr.length; maxlen > 0; maxlen--) {
// 判断长度是否除尽
if (len1 % maxlen === 0 && len2 % maxlen === 0) {
const _x = maxstr.slice(0, maxlen);

if (checkString(_x, str1) && checkString(_x, str2)) {
x = _x;
break;
}
}
}

return x;
};

执行用时,消耗内存
64 ms,49.32 MB

思路 2:str1 = n * x;str2 = m * x可推导出str1 + str2 = (n+m) * x = m * x + n * x = str2 + str1
所以重点来了,若存在最大公约数,那 str1 + str2 一定等于 str2 + str1
那最大公约数的字符串为gcd(str1.length, str2.length)的字符串。

1
2
3
4
5
6
7
// gcd 求公约数的函数
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b))

var gcdOfStrings = function (str1, str2) {
if(str1 + str2 !== str2 + str1) return ''
return str1.slice(0, gcd(str1.length, str2.length))
}

执行用时,消耗内存
50 ms,49.38 MB

总结:还是那句话,做算法一定要去找到对应的解题名称,而不是从语言层面去硬解。刚开始看到公约数了,但没有公约数的算法知识,所以第一次硬解没做出来


2、字符串的最大公因子
https://mrhzq.github.io/职业上一二事/算法学习/每日算法/2、字符串的最大公因子/
作者
黄智强
发布于
2024年1月13日
许可协议