LC409-最长回文串

145 阅读2分钟

题目名称:最长回文串

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

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

 

示例 1:

输入: s = "abccccdd"
输出: 7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。

示例 2:

输入: s = "a"
输出: 1

示例 3:

输入: s = "aaaaaccc"
输出: 7

提示:

  • 1 <= s.length <= 2000
  • s 只由小写 和/或 大写英文字母组成

思路分析

构造最长回文串首先要确定字符串中每个字符的出现次数,可以用hashmap实现。 得到每个字符的出现次数后再根据每个字符的不同次数判断回文串的长度。

1:如果字符出现次数是偶数,那么一定可以完美的加入到最后的回文串中。

2:如果字符出现次数是奇数,要分两种情况,如果是第一次遇到奇数的出现次数,那么可以全部加入最后生成的回文串中,相当于放到中间。

如果不是第一次出现奇数的次数,那么就只能减一变成偶数再加入回文串中。是否为第一次出现可以加入flag来实现辨别。

在一个回文串中,只有最多一个字符出现了奇数次,其余的字符都出现偶数次。可以遍历字符串,使用数组cnt统计每个字符出现的次数。定义int num = 0,然后遍历数组cnt:遇到偶数则直接将其值加到num;遇到奇数则先将其值-1再加到num。

如果有奇数次的字母出现,则最后的num再+1。最终返回num。这里使用isExistOdd来记录是否有奇数次的字母出现。

Code实现

public int longestPalindrome(String s) {
    int[] cnt = new int[82];
    for (char c: s.toCharArray()) {
        cnt[c - 'A'] ++;
    }

    int num = 0;
    int isExistOdd = 0;
    for (int i = 0; i < 82; i++) {
        if (cnt[i] != 0) {
            if (cnt[i] % 2 == 1) {
                num += cnt[i] - 1;
                isExistOdd = 1;
            } else {
                num += cnt[i];
            }
        }
    }
    return num + isExistOdd;
}

结果

Snipaste_2023-04-27_23-16-27.png

算法复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)