zl程序教程

您现在的位置是:首页 >  前端

当前栏目

【笔记】JavaScript版数据结构与算法——基础算法之“正则类”(459. 重复的子字符串)

2023-09-27 14:26:51 时间


重复的子字符串

1.题目

459. 重复的子字符串 - 力扣(LeetCode)

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

示例 1:

输入: “abab”
输出: True
解释: 可由子字符串 “ab” 重复两次构成。

示例 2:

输入: “aba”
输出: False

示例 3:

输入: “abcabcabcabc”
输出: True
解释: 可由子字符串 “abc” 重复四次构成。 (或者子字符串 “abcabc” 重复两次构成。)

题目模板

/**
 * @param {string} s
 * @return {boolean}
 */
var repeatedSubstringPattern = function(s) {

};

2.思路分析

见题解

3.所用到的方法

代码说明
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线
\s匹配任意的空白符
\d匹配数字
\b匹配单词的开始或结束
^匹配字符串的开始
$匹配字符串的结束
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符

4.题解及优化

课程解法

var repeatedSubstringPattern = function (s) {
  return /^(\w+)\1+$/.test(s)
}
  • ^:正则匹配开始
  • (\w+)
    • ():小括号表示捕获并记住
    • \w:匹配字母或数字或下划线
    • +:匹配多次
  • \1+:返回最后的第1+个子捕获匹配的子字符串(捕获的数目以左括号计数)
  • $:正则匹配结束
    在这里插入图片描述

其他小伙伴的解法

字符串includes

假设字符串由 n 个相同子串组成, 重复、掐头去尾后包含子串 2n - 2, 如果仍然包含原字符串即 2n - 2 > n,那就表示 n > 2

var repeatedSubstringPattern = function(s) {
  return (s + s).slice(1, -1).includes(s)
}

在这里插入图片描述

周期解法

周期串为s, 那么设定t表示最小周期, 数学中周期的表达式是

f(x+t)=f(x)

字符串中 ​s = item * count
那么我们需要找到最小周期 t = item.length

var repeatedSubstringPattern = function(s) {
  let len = s.length
  let i = 1
  while (i <= len / 2) {
    if (len % i === 0 && s.slice(0, i).repeat(len / i) === s) {
      return true
    }
    i++
  }
  return false
};

在这里插入图片描述