最长回文串
难度:
标签:
题目描述
给定一个包含大写字母和小写字母的字符串 s
,返回 通过这些字母构造成的 最长的回文串 。
在构造过程中,请注意 区分大小写 。比如 "Aa"
不能当做一个回文字符串。
示例 1:
输入:s = "abccccdd" 输出:7 解释: 我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
示例 2:
输入:s = "a" 输出:1
示例 3:
输入:s = "aaaaaccc" 输出:7
提示:
1 <= s.length <= 2000
s
只由小写 和/或 大写英文字母组成
代码结果
运行时间: 19 ms, 内存: 16.0 MB
/*
* 思路:
* 为了构造最长的回文串,我们需要统计每个字符出现的次数。
* 对于每个字符,如果其出现的次数为偶数,则这些字符可以完全放入回文串中。
* 如果出现次数为奇数,我们可以放入偶数部分,并且允许有一个奇数字符放在回文串的中心。
*/
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class LongestPalindromeStream {
public int longestPalindrome(String s) {
Map<Character, Long> charCount = s.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
int length = charCount.values().stream()
.mapToInt(count -> (int) (count / 2 * 2))
.sum();
return length < s.length() ? length + 1 : length;
}
}
解释
方法:
这个题解的思路是统计字符串中每个字符出现的次数,然后计算可以构成的最长回文串的长度。对于每个字符,如果它出现的次数是偶数,则可以全部使用;如果出现的次数是奇数,则只能使用偶数个。最后如果总长度是偶数且还有出现次数为奇数的字符未使用,可以再使用一个,放在回文串的中间。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
如何确定题目中提到的字符串中字符出现的次数是否有限制?
▷🦆
在解释中提到,如果总长度是偶数且还有出现次数为奇数的字符未使用,可以再使用一个放在回文串的中间。这里的逻辑是否意味着只有当答案是偶数时才考虑添加一个奇数次字符?
▷🦆
为什么在计算最长回文串时选择优先使用每个字符的偶数次,而不是尝试直接插入奇数次字符?
▷🦆
代码中用到了Counter类来统计字符频率,这个类的效率如何?是否存在比Counter更高效的统计方法?
▷