zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    000 初步使用Kotlin开发Android应用
    使用Kotlin开发Android应用
    使用Kotlin开发Android应用(IV):自定义视图和Android扩展
    使用Kotlin开发Android应用(III):扩展函数和默认值
    使用Kotlin开发Android应用(II):创建新工程
    使用Kotlin开发Android应用
    Retrofit2.2说明-简单使用
    Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)
    android开发环境 eclipse + android sdk配置笔记
    Android 百度地图定位(手动+自动) 安卓开发教程
  • 原文地址:https://www.cnblogs.com/yawenw/p/12952663.html
Copyright © 2011-2022 走看看