[算法学习] 最长回文串

RoLingG 算法 2024-04-11

每日算法 最长回文串

例题:409. 最长回文串

题目描述:

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

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

代码:

class Solution {
    public int longestPalindrome(String s) {
        int[] count = new int[128];
        int length = s.length();
        for(int i = 0; i < length; i++) {
            char c = s.charAt(i);
            count[c] ++;
        }
        int result = 0;
        for(int v : count) {
            result += v / 2 * 2;
            if (v % 2 == 1 && result % 2 ==0) {
                result ++;
            }
        }
        return result;
    }
}

小疑问:

result += v / 2 * 2; 这步是在干什么

回答:

这样做是因为 Count[n] 中有些字符是奇数个,除二之后能四舍五入掉一,再把二乘回去就可以知道实际上这个字符最大偶数个是多少。只要是偶数就可以形成回文串。当然经过 result += v / 2 * 2; 操作之后的字符是奇数个也能在当前回文串长度是偶数的时候加入进来,但只是能让长度++(因为经过 result += v / 2 * 2; 操作之后四舍五入舍的都是1)。

注意:

这一题里面的字符用的一般都是ASCII字符,我一开始的数组大小就只定义了32,所以要注意数组 count 的大小设置不能低于128,不然运行会报错数组大小问题。

GPT给的这个注意解释:

Java 中的 char 类型是以Unicode编码形式表示字符的。Unicode字符集包含了ASCII字符集,并且还包括了更广泛的字符范围。

在你的代码中,数组 count 的长度被定义为32,这实际上是个问题,因为在Java中,char 类型的范围是从0到65535(即Unicode字符集中的所有字符),而不仅仅是ASCII字符(范围是从0到127)。因此,如果字符串中的字符超出了ASCII范围,比如 'a' 的Unicode码点值是97,就会导致 count 数组越界。

为了修复这个问题,你可以将数组 count 的长度增加到65536,以确保可以正确统计所有字符的出现次数,而不会导致数组越界错误。

如果你将数组 count 的大小设置为128,而不再报错,那是因为128正好足够容纳ASCII字符集的全部范围。ASCII字符集包含了从0到127的字符,因此一个大小为128的数组可以准确地统计ASCII字符的出现次数,而不会导致数组越界错误。

从下面这两个表我们也能很清晰的看出来原因所在(主要因为这题的字符串都是字母,所以只要大小不小于128基本没事,保险起见的话设置成65535才是最稳健的)。

请输入图片描述

请输入图片描述

PREV
[算法学习] 验证回文串
NEXT
[算法学习] 二分查找

评论(0)

发布评论