「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」
最长回文串
LeetCode传送门 409. 最长回文串
题目
给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。
在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。
注意: 假设字符串的长度不会超过 1010。
Given a string s which consists of lowercase or uppercase letters, return the length of the longest palindrome that can be built with those letters.
Letters are case sensitive, for example, "Aa" is not considered a palindrome here.
Example:
Input: s = "abccccdd"
Output: 7
Explanation:
One longest palindrome that can be built is "dccaccd", whose length is 7.
Input: s = "a"
Output: 1
Input: s = "bb"
Output: 2
Constraints:
- 1 <= s.length <= 2000
- s consists of lowercase and/or uppercase English letters only.
思考线
解题分析
我们要根据一段字符串来组成回文数我们该怎么办呢?若我们把所有字符按出现重复的次数,排列起来
- 若字符串中没有任何一个重复的字符,则最长的回文字符串长度为
1,为其中的任意一个字符。 - 若字符串有重复,则所有重复的偶数个都可以组成回文串 a. 若其中一个字符出现次数为奇数,我们还可以多加一位,让其作为回文中心 b. 若没有任何一个字符出现的次数为奇数,则回文中心是两个相同的字符。
根据以上思考, 我们可以先设置一个 hashMap, 记录字符出现的次数。
然后我们设置一个变量counts记录可能的最长回文字符,然后遍历刚刚的hashMap,让所有满足条件的字符串的最大偶数个数都加上去,而且若存在奇数个时,我们记得要多加一个,让其作为回文中心。
function longestPalindrome(s: string): number {
const hash: Record<string, number> = {}
// 遍历字符串,用hash记录字符出现次数
for (let i = 0; i < s.length; i++) {
if (hash[s[i]]) {
hash[s[i]] += 1;
} else {
hash[s[i]] = 1;
}
}
// 字符 回文数加入的个数为 v/2 *2
let counts = 0;
Object.entries(hash).forEach(([key, val]) => {
counts += (val >> 1) * 2; // 记录每个字符串的最大偶数,并记录到counts中
if(val %2 !== 0 && counts %2 ===0 ) {// 若首次出现奇数个,记录下来
counts ++
}
})
return counts;
};
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。