持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
题目描述一
409. 最长回文串
难度 简单
给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的回文串 。
在构造过程中,请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串。
示例 1:
输入: s = "abccccdd"
输出: 7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
示例 2:
输入: s = "a"
输入: 1
提示:
1 <= s.length <= 2000s只由小写 和/或 大写英文字母组成
解析
- 创建对象,纪录每个字母出现的次数;
- 如果对象的值是奇数个,则记录一个作为中间的值;
- 统计偶数出现的次数,再加上中间的值(如果有的话)。
function longestPalindrome(s) {
const map = new Map();
for (let i = 0; i < s.length; i++) {
map.set(s[i], (map.get(s[i]) ?? 0) + 1);
}
let bothSide = 0;
let center = 0;
map.forEach((value) => {
const rem = value % 2;
bothSide += value - rem;
if (rem === 1) {
center = 1;
}
});
return bothSide + center;
};
题目描述二
5. 最长回文子串
难度 中等
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
示例 2:
输入: s = "cbbd"
输出: "bb"
提示:
1 <= s.length <= 1000s仅由数字和英文字母组成
解析
采用双指针。
找回文串的难点在于,回文串的的长度可能是奇数也可能是偶数,解决该问题的核心是从中心向两端扩散的双指针技巧。
如果输入相同的 l 和 r,就相当于寻找长度为奇数的回文串,如果输入相邻的 l 和 r,则相当于寻找长度为偶数的回文串
function longestPalindrome(s) {
let res = "";
const len = s.length;
for (let i = 0; i < len; i++) {
// 找到s[i]为中心的最长回文串, 寻找长度为奇数的回文串
const s1 = palindrome(s, i, i);
// 找到s[i]和s[i+1]为中心的最长回文串,寻找长度为奇数的回文串
const s2 = palindrome(s, i, i + 1);
res = res.length > s1.length ? res : s1;
res = res.length > s2.length ? res : s2;
}
return res;
}
const palindrome = (s, l, r) => {
const len = s.length;
// 从中心向两端扩散的双指针
while (l >= 0 && r < len && s[l] === s[r]) {
l--;
r++;
}
return s.substring(l + 1, r);
};