一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 6 天,点击查看活动详情。
回文子串
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例 1:
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
示例 2:
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
提示:
1 <= s.length <= 1000s由小写英文字母组成
思路分析
方法一
- 拿到题目的第一时间想到的就是粗暴解法;
- 定义 buildSubstrings 方法来获取字符串的所有子串;
- 定义 isPalindromic 来判断一个字符串是否为回文字符串;
- 得到所有子串后,遍历得到符合回文字符串的数量,返回即可。
方法二
其实,可以看到上述代码是比较繁琐,比较累赘的,那么我们可以从代码精简的程度来优化一下,尽可能多的使用现有的 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