【力扣】459.重复的子字符串|每日一题|刷题打卡

77 阅读2分钟

一、题目描述

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

 

示例 1:

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。

示例 2:

输入: s = "aba"
输出: false

示例 3:

输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)

 

提示:

  • 1 <= s.length <= 104
  • s 由小写英文字母组成

二、思路分析

  1. const len = s.length / 2: 计算字符串 s 的一半长度。这是因为如果一个字符串由重复的子字符串构成,那么子字符串的最大可能长度为字符串长度的一半。
  2. if (s.length % (i + 1) === 0) { ... }: 检查当前构建的子字符串的长度是否是字符串 s 的长度的因数。这是为了确保子字符串的长度是一个可能的重复单元。
  3. if (re + re !== s.substring(0, (i+1) * 2)) { continue }: 检查当前构建的子字符串是否与原始字符串 s 的前面一部分(长度为 (i+1) * 2)相同。如果不相同,说明当前子字符串不满足重复的条件,继续尝试下一个长度的子字符串。
  4. for (var j = 0; j < temp; j++) { ... }: 使用内部循环将当前构建的子字符串重复 temp 次,将结果存储在 str 变量中。
  5. 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
};