力扣L13--- 409.最长回文串(JAVA版)-2024年3月1日

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。
语法:

java 复制代码
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}。

java 复制代码
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)统计每个字母出现的次数: 我们需要统计每个字母出现的次数。使用哈希表来记录每个字母出现的次数,对于示例字符串,统计结果如下:

java 复制代码
{'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,0
2=0

因为存在过 次数为奇数的字母,所以要把回文串的总长度+1(意思也就是说偶数的全加进去,奇数不管是a还是b,你挑一个放在回文串的中间就可以)

所以4+0+0+2+1=7

(4)计算回文串的长度:

java 复制代码
4 + 2 + 1 = 7

最长回文串的长度为 7,例如 "dccaccd"。

4.代码实现

java 复制代码
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;


    }
}
相关推荐
雷神乐乐16 分钟前
File.separator与File.separatorChar的区别
java·路径分隔符
小刘|20 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
jjyangyou25 分钟前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
逊嘘40 分钟前
【Java语言】抽象类与接口
java·开发语言·jvm
van叶~42 分钟前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
简简单单做算法43 分钟前
基于Retinex算法的图像去雾matlab仿真
算法·matlab·图像去雾·retinex
morris1311 小时前
【SpringBoot】Xss的常见攻击方式与防御手段
java·spring boot·xss·csp
云卓SKYDROID1 小时前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员1 小时前
java导出word文件(手绘)
java·开发语言·word