一、题目描述
给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba"
输出: false
示例 3:
输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
提示:
1 <= s.length <= 104s由小写英文字母组成
二、思路分析
const len = s.length / 2: 计算字符串s的一半长度。这是因为如果一个字符串由重复的子字符串构成,那么子字符串的最大可能长度为字符串长度的一半。if (s.length % (i + 1) === 0) { ... }: 检查当前构建的子字符串的长度是否是字符串s的长度的因数。这是为了确保子字符串的长度是一个可能的重复单元。if (re + re !== s.substring(0, (i+1) * 2)) { continue }: 检查当前构建的子字符串是否与原始字符串s的前面一部分(长度为(i+1) * 2)相同。如果不相同,说明当前子字符串不满足重复的条件,继续尝试下一个长度的子字符串。for (var j = 0; j < temp; j++) { ... }: 使用内部循环将当前构建的子字符串重复temp次,将结果存储在str变量中。if (str === s) { return true }: 检查构建的重复子字符串str是否与原始字符串s完全相同。如果相同,说明字符串s由重复的子字符串构成,返回true。
整体逻辑:通过逐步构建不同长度的子字符串,并判断其是否能够重复构成原始字符串,来判断给定字符串是否由重复的子字符串构成
三、代码答案
/**
* @param {string} s
* @return {boolean}
*/
var repeatedSubstringPattern = function (s) {
if (s.length === 1) return false
const len = s.length / 2
let re = ''
for (var i = 0; i < len; i++) {
re += s[i]
if (s.length % (i + 1) === 0) {
// 这段是优化,减少内循环次数
if (re + re !== s.substring(0, (i+1) * 2)) {
continue
}
// 计算字符串 `s` 的长度除以当前子字符串的长度,得到重复的次数
let temp = s.length / (i + 1)
let str = ''
for (var j = 0; j < temp; j++) {
str += re
}
if (str === s) {
return true
}
}
}
return false
};