May LeetCoding Challenge22 之 比较器comparator、map按Value排成逆序、桶排序

本题需要统计字符个数,并按逆序排序,共有三种解法:

1.用数组存储排序,先将字符串转为字符数组,调用Arrays.sort方法对字符数组排序,将相同的字符存储在一个字符串中,将所有字符串存入list中,按照每个字符串长度由大到小进行排序,新建一个StringBuilder,将排好序的字符串依次添加到StringBuilder中,最后转成String输出。

2.HashMap存储排序,用HashMap统计字符及出现次数,存入count中,对count的value值进行排序,然后依次添加字符到StringBuilder中,最后转成String输出。

3.桶排序,用HashMap统计字符及出现次数,存入count中,遍历count得到最大的value,用ArrayList建立value个空桶,将字符放入桶中,桶的顺序是字符出现的频次,从后向前遍历每个桶中的字符,添加到StringBuilder中,最后转成String输出。

语法补充:

1.Comparator比较器复写方法

Collections.sort(list, new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getId() - o2.getId();
    }
};
list.sort(new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getId() - o2.getId();
    }
});
Collections.sort(list, (a, b) -> b.getId()-a.getId());

2.将map按Value大小逆序排序,需要利用map.entrySet()并存入list中[(Character1,Integer1), (Character2,Integer2)]

        //首先将count放入list
        List<Map.Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character, Integer>>(count.entrySet());//[(Character1,Integer1), (Character2,Integer2)]
        //用list对Comparator复写,实现按map的Value逆序排序
        list.sort(new Comparator<Map.Entry<Character, Integer>>(){
            @Override
            public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer>o2){
                return o2.getValue()-o1.getValue();
            }
        });

3.遍历map对象

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
  System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}

//遍历map中的键
for (Integer key : map.keySet()) {
  System.out.println("Key = " + key);
}
//遍历map中的值
for (Integer value : map.values()) {
  System.out.println("Value = " + value);
}

4.Python的Counter, 和 mostcommon 和 .join 和 sort的熟练使用

# Sort the strings by length from *longest* to shortest.
charStrings.sort(key=lambda string : len(string), reverse=True)
def frequencySort(self, s: str) -> str:

    # Count up the occurances.
    counts = collections.Counter(s)
    
    # Build up the string builder.
    string_builder = []
    for letter, freq in counts.most_common():
        # letter * freq makes freq copies of letter.
        # e.g. "a" * 4 -> "aaaa"
        string_builder.append(letter * freq)
    return "".join(string_builder)

JAVA

class Solution {
    public String frequencySort(String s) {
        if(s == null || s.isEmpty()) return s;
        StringBuilder res = new StringBuilder();
        //将字符串转成字符数组并排序
        char[] chars = s.toCharArray();
        Arrays.sort(chars);
        //将字符相同的存入一个字符串,并将所有字符串存入list
        List<String> charStrings = new LinkedList<>();
        StringBuilder temp = new StringBuilder();
        temp.append(chars[0]);
        for(int i = 1; i < chars.length; i++){
            if(chars[i] != chars[i-1]){
                charStrings.add(temp.toString());
                temp = new StringBuilder();
            }
            temp.append(chars[i]);
        }
        charStrings.add(temp.toString());
        //对list 按照字符串长度从大到小排序
        Collections.sort(charStrings, (a, b) -> b.length()-a.length());
        //将排序后的字符串依次存入结果
        for(String str : charStrings){
            res.append(str);
        }
        return res.toString();
    }
}
class Solution {
    public String frequencySort(String s) {
        StringBuilder res = new StringBuilder();
        Map<Character, Integer> count = new HashMap<>();
        for(char c: s.toCharArray()){
            count.put(c, count.getOrDefault(c, 0)+1);
        }
        //首先将count放入list
        List<Map.Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character, Integer>>(count.entrySet());//[(Character1,Integer1), (Character2,Integer2)]
        //用list对Comparator复写,实现按map的Value逆序排序
        list.sort(new Comparator<Map.Entry<Character, Integer>>(){
            @Override
            public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer>o2){
                return o2.getValue()-o1.getValue();
            }
        });
        for (Map.Entry<Character, Integer> map : list){
            for(int i = 0; i < map.getValue(); i++){
                res.append(map.getKey());
            }
        }
        return res.toString();
    }
}
class Solution {
    public String frequencySort(String s) {
        if(s == null || s.isEmpty()) return s;
        StringBuilder res = new StringBuilder();
        Map<Character, Integer> count = new HashMap<>();
        for(char c: s.toCharArray()){
            count.put(c, count.getOrDefault(c, 0)+1);
        }
        int maxFrequency = 0;
        for(Map.Entry<Character, Integer> entry: count.entrySet()){
            maxFrequency = Math.max(maxFrequency, entry.getValue());
        }
        System.out.println(maxFrequency);
        //申请一排桶,桶的顺序代表桶内字符出现的次数
        List<List<Character>> buckets = new ArrayList<>();
        //bug 这里写成LinkedList会超时,因为单个字符出现次数多的时候,需要访问的桶也增多。
        //ArrayList访问速度快,LinkedList增加删除速度快
        //构建空桶
        for(int i = 0; i <= maxFrequency; i++){
            buckets.add(new LinkedList<Character>());
        }
        //根据字符出现的次数放入对应的桶内
        for(Character key: count.keySet()){
            int freq = count.get(key);
            buckets.get(freq).add(key); //!!!桶排序最重要的一步
        }
        for(int i =buckets.size()-1; i >= 1; i--){
            for(Character c: buckets.get(i)){//一个桶内可能有多个字符
                for(int j = 0; j < i; j++){
                    res.append(c);
                }
            }
        }
        return res.toString();
    }
}

Python3

class Solution:
    def frequencySort(self, s: str) -> str:
        if not s: return s
    # Convert s to a list.
        s = list(s)
    # Sort the characters in s.
        s.sort()  
    # Make a list of strings, one for each unique char.
        charStrings = []
        temp = [s[0]]
        for c in s[1:]:
        # If the last character on string builder is different...
            if temp[-1] != c:
                charStrings.append("".join(temp))
                temp = []
            temp.append(c)
        charStrings.append("".join(temp))   
    # Sort the strings by length from *longest* to shortest.
        charStrings.sort(key=lambda string : len(string), reverse=True)
    
    # Convert to a single string to return.
    # Converting a list of strings to a string is often done
    # using this rather strange looking python idiom.
        return "".join(charStrings)
def frequencySort(self, s: str) -> str:

    # Count up the occurances.
    counts = collections.Counter(s)
    
    # Build up the string builder.
    string_builder = []
    for letter, freq in counts.most_common():
        # letter * freq makes freq copies of letter.
        # e.g. "a" * 4 -> "aaaa"
        string_builder.append(letter * freq)
    return "".join(string_builder)
def frequencySort(self, s: str) -> str:
    if not s: return s
    
    # Determine the frequency of each character.
    counts = collections.Counter(s)
    max_freq = max(counts.values())
    
    # Bucket sort the characters by frequency.
    buckets = [[] for _ in range(max_freq + 1)]
    for c, i in counts.items():
        buckets[i].append(c)
        
    # Build up the string.
    string_builder = []
    for i in range(len(buckets) - 1, 0, -1):
        for c in buckets[i]:
            string_builder.append(c * i)
            
    return "".join(string_builder)
原文地址:https://www.cnblogs.com/yawenw/p/12952663.html