回文串(Palindrome)是指正读和反读都相同的字符串,比如"madam"、"racecar"都是经典的对称结构。在解决LeetCode 409题时,我们需要理解几个关键点:
字符频率决定构造方式:回文串的构造本质上是对字符出现次数的合理利用。偶数次字符可以全部使用,奇数次字符则需要特殊处理。
大小写敏感特性:题目明确要求区分大小写,这意味着'A'和'a'被视为不同字符。这个细节直接影响字符统计的方式。
最长回文串的构成规则:
关键理解:回文串的对称性决定了字符使用的特殊规则。当所有字符都成对出现时,最大长度就是字符串本身;当存在奇数字符时,最大长度是所有偶数部分之和加1。
原始解法使用长度为58的数组是基于ASCII码值的考虑:
java复制int[] count = new int[58]; // 26(大写) + 6(间隔) + 26(小写) = 58
for(char c : s.toCharArray()){
count[c-'A']++; // 'A'=65最小,作为基准
}
更直观的替代方案是使用128长度的数组(覆盖所有ASCII字符):
java复制int[] count = new int[128]; // 直接使用字符ASCII码作为索引
for(char c : s.toCharArray()){
count[c]++;
}
核心算法逻辑可以简化为:
数学表达:
code复制maxLength = sum(even counts) + sum(odd counts - 1) + (hasOdd ? 1 : 0)
优化后的实现:
java复制int oddCount = 0;
for(int num : count){
oddCount += num % 2;
}
return s.length() - oddCount + (oddCount > 0 ? 1 : 0);
需要特别注意的特殊情况:
当字符集不明确时(如Unicode字符),可以使用HashMap:
java复制Map<Character, Integer> map = new HashMap<>();
for(char c : s.toCharArray()){
map.put(c, map.getOrDefault(c, 0)+1);
}
对于超长字符串(虽然本题限制2000),可以考虑并行统计:
java复制int[] count = new int[128];
s.chars().parallel().forEach(c -> count[c]++);
如果需要输出具体回文串而不仅是长度,可以扩展算法:
回文串问题在多个领域有实际应用:
错误示例:
java复制// 错误:未考虑大小写敏感
int[] count = new int[26];
for(char c : s.toCharArray()){
count[Character.toLowerCase(c)-'a']++;
}
调试方法:
常见错误:
java复制// 错误:直接加所有count,没有处理奇数
for(int num : count){
res += num;
}
正确逻辑应该是:
java复制for(int num : count){
res += num % 2 == 0 ? num : num - 1;
}
测试用例建议:
java复制if((num & 1) == 1) // 奇数
对比类似问题:
理解这些变种有助于深化对字符串处理的理解。在实际面试中,面试官可能会从简单回文构造问题延伸到更复杂的字符串算法考察。