給出一個包含大小寫字母的字符串。求出由這些字母構成的最長的回文串的長度是多少。
數據是大小寫敏感的,也就是說,"Aa"
並不會被認為是一個回文串。
注意事項
假設字符串的長度不會超過 1010
。
樣例
給出 s = "abccccdd"
返回 7
一種可以構建出來的最長回文串方案是 "dccaccd"
。
這個題關鍵的一點就是如何處理奇數個的字符。
如果處理好了奇數個字符,那么這個題就會迎刃而解。原因在於如果是偶數個的字符,一定可以構造回文數。但是奇數個的就不行。所有的奇數個的字符數都要減去1。
最后所有的奇數字符串中只可以保留一個完整的,就是它是多長就在最大回文串中加上多少。但是可想而知,這個奇數的回文串一定是位於整個調整后的回文串的最中間。
否者難以構成回文串。
比如"abbba"是個回文串但是有3個"b",只能放中間才能構成回文串。如果是"abbbccca"有3個"b",3個"c"這時就無法構成回文串,如果想構成回文串那么這兩個奇數個的字符
要有一個字符的個數減去1,然后把剩下的那個個數為3的字符放在最中間"acbbbca"或者"abcccba"當然對稱的部分順序也是可以調換的"cabbbac","bacccab"。
最關鍵的一步就是如何處理奇數個的字符。
通過前面的敘述應該很明白了。就是奇數個的字符。都減去1,再在最后的基礎上,判斷是否有奇數個的字符。如果有那么結果加上1返回就可以了。
想了很久,調試了很久終於把這個問題給解決了。
public class MaxHuiWenChuan { public int longestPalindrome(String s) { // Write |your code here List<Integer> list = getList(s); int i = getMaxHuiWenShu(list); System.out.println(i); return i; } /** * 解析字符串,獲得每個字符的個數,並返回個數list。 */ public List<Integer> getList(String s) { List<Character> list = new ArrayList<>(); for (char ll = 'a'; ll <= 'z'; ll++) { list.add(ll); } for (char ll = 'A'; ll <= 'Z'; ll++) { list.add(ll); } List<Integer> list1 = new ArrayList<Integer>(); for (int i = 0; i < list.size(); i++) { int k = 0; for (int j = 0; j < s.length(); j++) { if (list.get(i).equals(s.charAt(j))) { k++; } } if (k != 0) { list1.add(k); } } return list1; } /** * 對list集合進行分析。並確定最長的回文數。 */ public int getMaxHuiWenShu(List<Integer> list) { int count = 0; if (list.size() == 1) { count = list.get(0); return count; } boolean hasJiShu = false; for (int i = 0; i < list.size(); i++) { count += (list.get(i) / 2) * 2; if (list.get(i) % 2 == 1) { hasJiShu = true; } } if (hasJiShu) { count++; } return count; } public static void main(String[] args) { MaxHuiWenChuan m = new MaxHuiWenChuan(); m.longestPalindrome("abccccdd"); m.longestPalindrome("aaa"); m.longestPalindrome("aaabbccc"); m.longestPalindrome("aaabb"); } }
當然上面的是我自己寫的。下面附上一個摘自網上的,代碼很精練。值得借鑒。
public class Solution { /** * @param s a string which consists of lowercase or uppercase letters * @return the length of the longest palindromes that can be built */ public int longestPalindrome(String s) { // Write your code here if(s == null || s.length() == 0){ return 0; } boolean hasOod = false; int[] record = new int[52]; for(int i = 0;i<record.length;i++){ record[i] = 0; } for(int i = 0;i<s.length();i++){ char temp = s.charAt(i); if(Character.isUpperCase(temp)){ record[temp - 'A' + 0]++; }else{ record[temp - 'a' + 26]++; } } int result = 0; for(int i = 0;i<record.length;i++){ result += (record[i]/2)*2; if(record[i]%2 == 1){ hasOod = true; } } if(hasOod) result++; return result; } }