1.题目描述
2.知识点
注1:向下取整是将一个数值向下舍入到最接近的整数,但不超过这个数值的整数。具体规则如下:
对于正数,向下取整后得到的整数是不大于原数值的最大整数;
对于负数,向下取整后得到的整数是不小于原数值的最大整数。
例如:
注2:toCharArray() 是 Java 中 String 类的一个方法,它的作用是将字符串转换为字符数组。
例如,假设有一个字符串 s = “hello”,调用 s.toCharArray() 将返回一个字符数组 [‘h’, ‘e’, ‘l’, ‘l’, ‘o’],其中每个字符对应字符串 s 中的一个字符。
注3:count.getOrDefault(c, 0) 是 Java 中 HashMap 类的方法,它的作用是获取哈希表中指定键的值,如果该键不存在,则返回指定的默认值。
如果哈希表中存在键 c,则返回键 c 对应的值。
如果哈希表中不存在键 c,则返回默认值 0。
语法:
V getOrDefault(Object key, V defaultValue)
其中,key 是要查找的键,defaultValue 是默认值。
在这个问题中,我们使用 count.getOrDefault(c, 0) 来获取每个字符在哈希表中的出现次数。如果字符 c 在哈希表中存在,则返回对应的出现次数;如果不存在,则返回默认值 0,表示该字符还没有出现过。
注4:我们首先将 hasOdd 初始化为 false,因为我们一开始不知道字符串中是否存在出现次数为奇数的字符。然后在统计每个字符的出现次数时,如果发现有某个字符出现的次数是奇数,则将 hasOdd 设置为 true。这样在遍历完字符串后,我们就能根据 hasOdd 的值确定是否存在出现次数为奇数的字符。
因此,将 hasOdd 初始值设为 false 是为了在开始时保持一个初始状态,并在遍历字符串时根据情况更新它的值。
**注5:**调用 cnt.values() 方法会返回一个包含 cnt 中所有值的集合,这个集合的类型是 Collection,其中 V 是哈希表中值的类型。在这个问题中,cnt 中的值是整数类型,因此 Collection 的类型是 Collection。
通过调用 cnt.values() 方法,我们可以获取到 cnt 哈希表中所有字母的出现次数,这些出现次数存储在一个集合中,我们可以通过遍历这个集合来获取每个字母的出现次数。
现在我们调用 cnt.values() 方法,将返回一个包含哈希表 cnt 中所有值的集合。在这个例子中,集合中的元素是整数,表示每个字母的出现次数。因此,集合中的元素是 {3, 2, 1}。
HashMap<Character, Integer> cnt = new HashMap<>();
cnt.put('a', 3); // 'a' 出现了 3 次
cnt.put('b', 2); // 'b' 出现了 2 次
cnt.put('c', 1); // 'c' 出现了 1 次
for (int charCnt : cnt.values()) {
System.out.print(charCnt+" "); // 输出每个字母的出现次数
}
//输出3 2 1
3.思路与具体例子
假设我们有输入字符串 s = “abccccdd”。
(1)统计每个字母出现的次数: 我们需要统计每个字母出现的次数。使用哈希表来记录每个字母出现的次数,对于示例字符串,统计结果如下:
{'a': 1, 'b': 1, 'c': 4, 'd': 2}
(2)构造回文串的过程:
对于出现偶数次的字母,我们可以将其全部添加到回文串中,因为它们可以完全对称地构成回文串的一半。
对于出现奇数次的字母,我们只能取其偶数部分,因为回文串是对称的,如果将所有奇数次的字母都添加到回文串的两端,将无法构成一个对称的回文串。但我们可以选择其中一个字母放在回文串的中心。
(3)计算回文串的长度:
1)对于偶数次出现的字母,直接将其出现次数添加到回文串长度中。
2)对于奇数次出现的字母,取其偶数部分,即将其除以 2 后向下取整再乘以 2,然后将结果添加到回文串长度中。
当一个字母出现的次数是奇数时,我们只能取其偶数部分来构造回文串。我们需要将这个奇数次出现的字母数量减少到偶数。
具体做法是,将这个奇数次出现的字母数量除以 2 后取整,然后再乘以 2。这样得到的结果就是比原始奇数次出现的数量小的最大的偶数。
3)如果存在出现次数为奇数的字母,最后回文串长度加上 1。
举个例子abccccdd 总长度是8
a:1 ,b:1 ,c=4, d=2
因为a是奇数,所以1/2=0.5 ,向下取整是0,02=0
因为b是奇数,所以1/2=0.5,向下取整是0,02=0
因为存在过 次数为奇数的字母,所以要把回文串的总长度+1(意思也就是说偶数的全加进去,奇数不管是a还是b,你挑一个放在回文串的中间就可以)
所以4+0+0+2+1=7
(4)计算回文串的长度:
4 + 2 + 1 = 7
最长回文串的长度为 7,例如 “dccaccd”。
4.代码实现
class Solution {
public int longestPalindrome(String s) {
int length=0;//会文创的总长度;
boolean oddChar=false;//是否存在字数为奇数的字母
//构造一个空的哈希表,用来存储每个字母出现的字数
HashMap<Character,Integer> cnt=new HashMap<>();
//s.toCharArray()将字符串变成字符数组
// cnt.getOrDefault(c, 0) 是 Java 中 HashMap 类的方法,用于获取哈希表中指定键的值。如果该键存在,则返回对应的值;如果该键不存在,则返回指定的默认值。
// cnt.getOrDefault(c, 0) 指定键为字符c变量 设置默认的值为0
for(char c:s.toCharArray())
{
cnt.put(c,cnt.getOrDefault(c,0)+1);
}
for(int charCnt:cnt.values())
{
if(charCnt%2==0)
{
length=length+charCnt;//把字母出现的是偶数次的 全部加到总串串
}
else
{
length=length+charCnt-1;//把字母出现的是奇数次的,先取到最大不超过该奇数的偶数。
oddChar=true;//说明存在字母出现是奇数次的
}
}
if(oddChar==true)
{
return length+1;//把奇数次字母,取一个的放在串的中间
}
return length;
}
}