409.最长回文串(JS)

88 阅读3分钟

最长回文串

Category Difficulty Likes Dislikes
algorithms Easy (49.37%) 62 -
Tags

hash-table

Companies
给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。

在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。

注意: 假设字符串的长度不会超过 1010。

示例 1:

输入:
"abccccdd"

输出:
7

解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。

1

回文是前后读起来都一样

那么如果这个回文字符串是偶数的话

那就是对称的,aaabbxxbbaaa

如果我们那把每个字母的个数统计起来

比如

字母alen就是6

字母blen就是4

字母xlen就是2

那回文的长度就是 每个字母的len累积

即,6+4+2

但是如果

字母alen就是7

即长度是奇数

能在回文中添加的长度据

parseInt(len/2)*2

这里使用parseInt()

比如aaa的长度就是3

parseInt(3/2)*2 === 2

这样我们就知道

在回文长度是偶数的情况下

回文的总长度是字母的parseInt(len/2)*2累积

那如果回文长度是奇数的话

我们就可以随意的在中间添加一个多出来的字母

比如,``aaabbxoxbbaaa`

当我们在求最长的时候

我们一般尽可能的是要奇数的

所以当我们原本的长度是偶数

ret % 2 === 0

我们还有多出来的字母

比如任意某个字母的

len % 2 === 1

我们就可以给re++

思路清楚后

我们第一个遇到的问题就是

如何计算每个字母的次数

这里我们利用charCodeAt

可以把字母转换为数字

比如

console.log('a'.charCodeAt()); // 97
console.log('A'.charCodeAt()); // 65
console.log('z'.charCodeAt()); // 122
console.log('Z'.charCodeAt()); // 90

那我们把这数字作为数组的下标,那么该下标的值做为字母次数

	let count = Array(128).fill(0)
	for (const c of s) {
		count[c.charCodeAt()]++
	}

这里使用128的长度是因为,简单的ASCII表示0到127

我们当然可以取的更低,但是需要知道映射,挺麻烦的,简单取128就可以了

我们使用一个ret来记录回文长度

let ret = 0
for (const len of count) {
  if (len !== 0) {
    ret += parseInt(len / 2) * 2
    if (len % 2 === 1 && ret % 2 === 0) {
      ret++
    }
  }
}

最终的代码就是

/*
 * @lc app=leetcode.cn id=409 lang=javascript
 *
 * [409] 最长回文串
 */
/**
 * @param {string} s
 * @return {number}
 */
var longestPalindrome = function (s) {
	let count = Array(128).fill(0)
	for (const c of s) {
		count[c.charCodeAt()]++
	}
	let ret = 0
	for (const item of count) {
		if (item !== 0) {
			ret += parseInt(item / 2) * 2
			if (item % 2 === 1 && ret % 2 === 0) {
				ret++
			}
		}
	}
	return ret
};

复杂度分析

时间复杂度: O(n)

n为 s 的长度,至少遍历每个字符一次。

空间复杂度: O(1) 我们需要开辟额外空间来计数,其大小为 s 中字母的个数,我们都知道字母最多为26个。