題目描述:
給定一個字符串,請將字符串里的字符按照出現的頻率降序排列。
示例 1:
輸入:
"tree"
"tree"
輸出:
"eert"
"eert"
解釋:
'e'出現兩次,'r'和't'都只出現一次。
因此'e'必須出現在'r'和't'之前。此外,"eetr"也是一個有效的答案。
'e'出現兩次,'r'和't'都只出現一次。
因此'e'必須出現在'r'和't'之前。此外,"eetr"也是一個有效的答案。
示例 2:
輸入:
"cccaaa"
"cccaaa"
輸出:
"cccaaa"
"cccaaa"
解釋:
'c'和'a'都出現三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正確的,因為相同的字母必須放在一起。
'c'和'a'都出現三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正確的,因為相同的字母必須放在一起。
示例 3:
輸入:
"Aabb"
"Aabb"
輸出:
"bbAa"
"bbAa"
解釋:
此外,"bbaA"也是一個有效的答案,但"Aabb"是不正確的。
注意'A'和'a'被認為是兩種不同的字符。
此外,"bbaA"也是一個有效的答案,但"Aabb"是不正確的。
注意'A'和'a'被認為是兩種不同的字符。
解題思路:
用一個map來存每個字符出現的次數(鍵為字符,值為出現的次數),再將map中的entry按值來從大到小排序,然后再連接起來(根據map的值對應的key進行拼接)。
Map沒有按值排序的方法,java有Comparator比較器接口,但要求的參數是list,我們可以通過Arraylist構造函數把map.entrySet()轉化為list,就可以用比較器了。
Comparator比較器接口:
我們若需要控制某個類的次序,而該類本身不支持排序(即沒有實現Comparable接口);我們可以建立一個“比較器”來進行排序。這個“比較器”只需要實現Comparator接口即可。
Collections.sort(list,
new
PriceComparator())
參數一:需要排序的list
參數二:比較器,實現Comparator接口的類,返回一個
int
型的值,就相當於一個標志,告訴sort方法按什么順序來對list進行排序。
Comparator是個接口,可重寫compare()及equals()這兩個方法,用於比較功能;如果是
null
的話,就是使用元素的默認順序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f,g這樣,當然數字也是這樣的。
compare(a,b)方法:根據第一個參數小於、等於或大於第二個參數分別返回負整數、零或正整數。
equals(obj)方法:僅當指定的對象也是一個 Comparator,並且強行實施與此 Comparator 相同的排序時才返回
true
。
代碼實現:
import java.util.*; public class FrequencySort { public static String frequencySort(String s) { if (s.length() < 3){ return s; } // 查找表(將數據存到一個表里,然后查找)map查找比list更優(更適合查找) Map<Character, Integer> counter = new HashMap<>(); for (int i = 0; i < s.length(); i++) { counter.put(s.charAt(i), counter.getOrDefault(s.charAt(i), 0) + 1); } //通過Arraylist構造函數把map.entrySet()轉化為list(map沒有按值排序的方法,我們要把map轉化為list) List<Map.Entry<Character, Integer>> list = new ArrayList<>(counter.entrySet()); //用Comparator比較器進行排序 Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>() { @Override public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) { //從大到小逆序排序 return o1.getValue() > o2.getValue() ? -1 : 1; } }); StringBuilder res = new StringBuilder(); //遍歷排好序的列表,得到排好序的集合,然后按值遍歷,將鍵key放到res中,輸出字符串) for (Map.Entry<Character, Integer> entry : list) { //對每一個值進行遍歷,例如a出現三次,遍歷3次,將a加入res,e出現2詞,遍歷2次,將e加入res...... for (int i = 0; i < entry.getValue(); i++) { res.append(entry.getKey()); } } return res.toString(); } public static void main(String[] args){ String str = "traaaee"; System.out.print(frequencySort(str)); } }