【问题标题】:Leetcode Problem 451. Sort Characters By Frequency PriorityQueue sorting problemLeetcode 451. 按频率对字符排序 PriorityQueue 排序问题
【发布时间】:2020-12-13 16:21:22
【问题描述】:

public static String frequencySort(String s) {

    String answer = "";
    
    HashMap<Character, Integer> map = new HashMap<>();
    
    for(int i = 0; i < s.length(); i++) {
        
        map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
        
    }
    //System.out.println(map.get('l'));
    //System.out.println(map.get('e'));
    
    PriorityQueue<Character> q = new PriorityQueue<>(new Comparator<Character>() {

        @Override
        public int compare(Character o1, Character o2) {
            
            if(map.get(o1) == map.get(o2)) {
                //System.out.println("o1 - o2: " + o1 + o2 + " " + (o1 - o2));
                return o2 - o1;
            }
            
            else {
                return map.get(o2) - map.get(o1);
            }
        }
    });
    
    for(int i = 0; i < s.length(); i++) {
        q.add(s.charAt(i));
    }
    
    while(!q.isEmpty()) {
        answer += String.valueOf(q.poll());
    }
    
    return answer;
}

我的代码看起来像这样,但我不知道为什么有时当频率相同但队列没有轮询我在比较器中写入的字符时,例如它输出为 ccwccwwwcwwwwccwwcccwcwwcw

【问题讨论】:

    标签: java hashmap comparator priority-queue


    【解决方案1】:

    看起来不错!不过不确定您的错误,这只会在 Java 中传递而不使用 PriorityQueue:

    public final class Solution {
        public static final String frequencySort(
            String s
        ) {
            Map<Character, Integer> countmap = new HashMap<>();
    
            for (char character : s.toCharArray()) {
                countmap.put(character, 1 + countmap.getOrDefault(character, 0));
            }
    
    
            List<Character>[] bucket = new List[s.length() + 1];
    
            for (char key : countmap.keySet()) {
                int frequency = countmap.get(key);
    
                if (bucket[frequency] == null) {
                    bucket[frequency] = new ArrayList<>();
                }
    
    
                bucket[frequency].add(key);
            }
    
            StringBuilder sb = new StringBuilder();
    
            for (int pos = bucket.length - 1; pos >= 0; pos--)
                if (bucket[pos] != null)
                    for (char character : bucket[pos])
                        for (int i = 0; i < pos; i++) {
                            sb.append(character);
                        }
    
    
            return sb.toString();
        }
    }
    

    以下是 LeetCode 的一些官方使用 cmets 的解决方案:

    public String frequencySort(String s) {
            
        if (s == null || s.isEmpty()) return s;
        
        // Create a sorted Array of chars.
        char[] chars = s.toCharArray();
        Arrays.sort(chars);
        
        // Convert identical chars into single Strings.
        List<String> charStrings = new ArrayList<String>();
        StringBuilder currentString = new StringBuilder();
        currentString.append(chars[0]);
        for (int i = 1; i < chars.length; i++) {
            if (chars[i] != chars[i - 1]) {
                charStrings.add(currentString.toString());
                currentString = new StringBuilder();
            }
            currentString.append(chars[i]);
        }
        charStrings.add(currentString.toString());
            
        // Our comparator is (a, b) -> b.length() - a.length().
        // If a is longer than b, then a negative number will be returned
        // telling the sort algorithm to place a first. Otherwise, a positive
        // number will be returned, telling it to place a second.
        // This results in a longest to shortest sorted list of the strings.
        Collections.sort(charStrings, (a, b) -> b.length() - a.length());
        
        // Use StringBuilder to build the String to return.
        StringBuilder sb = new StringBuilder();
        for (String str : charStrings) sb.append(str);
        return sb.toString();
    }
    
    public String frequencySort(String s) {
    
        // Count up the occurances.
        Map<Character, Integer> counts = new HashMap<>();
        for (char c : s.toCharArray()) {
            counts.put(c, counts.getOrDefault(c, 0) + 1);
        }
                
        // Make a list of the keys, sorted by frequency.
        List<Character> characters = new ArrayList<>(counts.keySet());        
        Collections.sort(characters, (a, b) -> counts.get(b) - counts.get(a));
    
        // Convert the counts into a string with a sb.
        StringBuilder sb = new StringBuilder();
        for (char c : characters) {
            int copies = counts.get(c);
            for (int i = 0; i < copies; i++) {
                sb.append(c);
            }
        }
        return sb.toString();
    }
    
    public String frequencySort(String s) {
            
        if (s == null || s.isEmpty()) return s;
        
        // Count up the occurances.
        Map<Character, Integer> counts = new HashMap<>();
        for (char c : s.toCharArray()) {
            counts.put(c, counts.getOrDefault(c, 0) + 1);
        }
        
        int maximumFrequency = Collections.max(counts.values());
        
        // Make the list of buckets and apply bucket sort.
        List<List<Character>> buckets = new ArrayList<>();
        for (int i = 0; i <= maximumFrequency; i++) {
            buckets.add(new ArrayList<Character>());
        }
        for (Character key : counts.keySet()) {
            int freq = counts.get(key);
            buckets.get(freq).add(key);
        }
    
        // Build up the string. 
        StringBuilder sb = new StringBuilder();
        for (int i = buckets.size() - 1; i >= 1; i--) {
            for (Character c : buckets.get(i)) {
                for (int j = 0; j < i; j++) {
                    sb.append(c);
                }
            }
        }
        return sb.toString();
    }
    

    此解决方案使用类似于您的优先级队列(在此 link 的评论中):

    class Solution {
        public String frequencySort(String s) {
            PriorityQueue<Map.Entry<Character, Integer>> maxHeap =
                    new PriorityQueue<>((a, b) -> b.getValue() - a.getValue());
            Map<Character, Integer> frequency = new HashMap<>();
            for (Character c : s.toCharArray()) {
                frequency.put(c, frequency.getOrDefault(c, 0) + 1);
            }
            maxHeap.addAll(frequency.entrySet());
            StringBuilder sb = new StringBuilder();
            while (maxHeap.size() > 0) {
                Map.Entry<Character, Integer> entry = maxHeap.remove();
                for (int i = 0; i < entry.getValue(); i++) {
                    sb.append(entry.getKey());
                }
            }
            return sb.toString();
        }
    }
    

    参考文献

    • 有关更多详细信息,请参阅Discussion Board,您可以在其中找到大量解释清楚且公认的解决方案,其中包含各种languages,包括低复杂度算法和渐近runtime/memory 分析@ 987654326@, 2.

    【讨论】:

      猜你喜欢
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 2014-01-10
      • 1970-01-01
      相关资源
      最近更新 更多