Given a string, sort it in decreasing order based on the frequency of characters.
Example 1:
Input:
"tree"
Output:
"eert"
Explanation:
'e' appears twice while 'r' and 't' both appear once.
So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer.
Example 2:
Input:
"cccaaa"
Output:
"cccaaa"
Explanation:
Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer.
Note that "cacaca" is incorrect, as the same characters must be together.
// correct
class Solution {
public String frequencySort(String s) {
// use some data struc to store the freq
HashMap<Character, Integer> map = new HashMap<>();
for(Character c : s.toCharArray()){
if(!map.containsKey(c)){
map.put(c, 1);
}else{
map.put(c, map.get(c) + 1);
}
}
StringBuilder sb = new StringBuilder();
// put the map entry into a max heap , accroding to the freq
// pop all, add it to the string
PriorityQueue<Map.Entry<Character, Integer>> pq = new PriorityQueue<>((a1, a2) -> a2.getValue().compareTo(a1.getValue())); // lambda expression, getValue(), a2.compareTo(a1) is maxHeap
for(Map.Entry<Character, Integer> entry: map.entrySet()){ // Map.Entry<> , map.entrySet()
pq.offer(entry);
}
while(!pq.isEmpty()){
Map.Entry<Character, Integer> entry = pq.poll(); // can only poll once, Map.Entry<>
char c = entry.getKey();
int freq = entry.getValue();
while(freq > 0){ // append freq times
sb.append(c);
freq--;
}
}
return sb.toString();
// still not familiar with the map entry set, and get value () ? and the entry set in max heap
// and lambda expression for custom comparison
// for (Map.Entry<String, String> entry : map.entrySet())
// System.out.println(entry.getKey() + "/" + entry.getValue());
// https://dzone.com/articles/using-lambda-expression-sort
// personList.sort((p1, p2) -> p1.firstName.compareTo(p2.firstName));
// PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);
}
}