LeetCode 热题 HOT — 回文子串

115 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 6 天,点击查看活动详情

回文子串

原题地址

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"

示例 2:

输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

提示:

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

思路分析

方法一

  1. 拿到题目的第一时间想到的就是粗暴解法;
  2. 定义 buildSubstrings 方法来获取字符串的所有子串;
  3. 定义 isPalindromic 来判断一个字符串是否为回文字符串;
  4. 得到所有子串后,遍历得到符合回文字符串的数量,返回即可。

方法二

其实,可以看到上述代码是比较繁琐,比较累赘的,那么我们可以从代码精简的程度来优化一下,尽可能多的使用现有的 API,来观察耗时。可以看到结果中时间是减少了一百多毫秒的。

AC 代码

方法一

/**
 * @param {string} s
 * @return {number}
 */
var countSubstrings = function(s) {
    const allSubs = buildSubstrings(s)
    let res = 0
    allSubs.forEach(item=>{
        if(isPalindromic(item)) res++
    })
    return res
};

// 构建一个字符串的所有子串
var buildSubstrings = function (s) {
   const res = []
   const len = s.length
   for (let i = 0; i < len; i++) {
      for (let j = i + 1; j < len + 1; j++) {
         res.push(s.slice(i, j))
      }
   }
   return res
};

// 判断一个字符串是否为回文字符串
var isPalindromic = function (s) {
    const len = s.length
    for (let i = 0; i < len / 2; i++) {
        if (s.charAt(i) != s.charAt(len - i - 1)) {
            return false
        }
    }
    return true
}

结果:

  • 执行结果: 通过
  • 执行用时:580 ms, 在所有 JavaScript 提交中击败了6.01%的用户
  • 内存消耗:83.8 MB, 在所有 JavaScript 提交中击败了5.00%的用户
  • 通过测试用例:130 / 130

方法二

/**
 * @param {string} s
 * @return {number}
 */
var countSubstrings = function(s) {
    let res = 0
    const len = s.length
    for (let i = 0; i < len; i++) {
      for (let j = i + 1; j < len + 1; j++) {
          const temp = s.slice(i, j)
          if(isPalindromic(temp))
            res++
      };
   };
   return res
};

// 判断一个字符串是否为回文字符串
var isPalindromic = function (s) {
    const len = s.length
    for (let i = 0; i < len / 2; i++) {
        if (s.charAt(i) != s.charAt(len - i - 1)) {
            return false
        }
    }
    return true
}

结果:

  • 执行结果: 通过
  • 执行用时:444 ms, 在所有 JavaScript 提交中击败了11.09%的用户
  • 内存消耗:47.1 MB, 在所有 JavaScript 提交中击败了48.09%的用户
  • 通过测试用例:130 / 130

END