一、題目描述
給定一個包含大寫字母和小寫字母的字符串,找到通過這些字母構造成的最長的迴文串。
在構造過程中,請注意區分大小寫。比如 "Aa"
不能當做一個迴文字符串。
注意:
假設字符串的長度不會超過 1010。
示例 1:
輸入:
“abccccdd”
輸出:
7
解釋:
我們可以構造的最長的迴文串是"dccaccd", 它的長度是 7。
二、解法
本題思路簡單,就是統計每個字符出現的次數,並且只能存在一個出現過奇數次的字符,其它出現過奇數次的字符要只能取 n - 1 次。
2.1 自己的常規解法,多次使用 if 判斷
class Solution {
public int longestPalindrome(String s) {
int[] num = new int[52]; //嚴格聲明瞭 52 個空間的數組
int index = 0;
//對數組進行初始化(其實不必)
for(int i = 0; i< num.length; i++) {
num[i] = 0;
}
//統計字母出現的次數
for(char c: s.toCharArray()) {
//第一次使用 if
index = (c - 'a') >= 0 ? (c - 'a') : (c - 'A') + 26;
num[index]++;
}
int flag = 0;
int sum = 0;
//統計迴文串長度
for(int i = 0; i < num.length; i++) {
//只能加一個完整的奇數
if((num[i] % 2 > 0) && flag == 0) {//第二次使用 if
sum += num[i];
flag = 1;
} else {
// 如果是偶數,直接相加,如果是奇數,減一再加
//第三次使用if
sum = (num[i] % 2 == 0) ? sum + num[i] : sum + num[i] - 1;
}
}
return sum;
}
}
自己的代碼看起來很臃腫囉嗦
2.2 leecode 官方解答
class Solution {
public int longestPalindrome(String s) {
int[] num = new int[58]; //直接聲明爲長度爲 58 的數組,可以省去判斷
for(char c: s.toCharArray()) {
num[c - 'A']++; //省去一次 if
}
int sum = 0;
for(int i = 0; i < num.length; i++) {
//直接用 sum % 2 來判斷是否有奇數,省去一個變量
if(num[i] % 2 > 0 && sum % 2 == 0) {
sum += num[i];
} else {
//騷操作,直接就省去了判斷是否爲奇數了,記住這種操作!!!
//又省去一次 if
sum += num[i] / 2 * 2;
}
}
return sum;
}
}
3.3 評論區大神解答
class Solution {
public int longestPalindrome(String s) {
// 找出可以構成最長迴文串的長度
int[] arr = new int[58];
for(char c : s.toCharArray()) {
arr[c]++;
}
int count = 0;
for (int i : arr) {
count += (i % 2); //1. 統計奇數出現的次數
}
return count == 0 ? s.length() : (s.length() - count + 1);//2.出現多少個奇數,就用字符串的總長度減這個值,意思是把它們都記錄成偶數,然後再加 1,因爲可以有一次shi'yo
//1 和 2 結合起來是真的騷
}
}