题目主要信息

1、字符串包含小写英文和数字,统计字符的个数

2、按照出现次数从多到少进行排序,如果个数相同,按照ASCII码从小到大排序输出。

方法一:暴力方法

具体做法

直接遍历字符串,记录每个字符出现的次数,并遍历得到一个出现个数最大的,依次从最多的进行减一操作,遍历原数组,找到与当前个数相等的,输出即可。如下abbzcccyy

alt

Java代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String s;
        try{
            while((s=bf.readLine())!=null)
            {
                System.out.println(count(s).toString());
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    public static StringBuilder count(String str)
    {
        char[] chars = str.toCharArray();
        int[] chArray=new int[129];
        //字符对应ascll码值下标元素自增来统计数量
        for(char i:chars)
            chArray[(int)i]++;
        int max=0;
        //找出字符数量最多的ascll码值
        for(int i=0;i<chArray.length;i++)
            if(max<chArray[i])
                max=chArray[i];
        StringBuilder sb=new StringBuilder();
        //按数量从大到小添加到可变字符序列sb
        while(max!=0)
        {
            //遍历找到与当前max相等的字符
            for(int i=0;i<chArray.length;i++){
                if(chArray[i]==max)
                    sb.append((char)i);
            }
            //max减1 进入下一轮遍历
            max--;
        }
        return sb;
    }
}

复杂度分析

  • 时间复杂度:O(n2)O(n^2),一个while循环嵌套一个for循环。
  • 空间复杂度:O(n)O(n)一个临时存字符的数组。

方法二:借助HashMap或者TreeMap

具体做法

Java中有很多集合,例如HashMap或者自带排序功能的TreeMap等,这里给出使用HashMap的方法。

  1. 遍历字符串,将字符:字符出现次数存入HashMap中
  2. 将HashMap放入ArrayList中, 并对其进行排序,重写排序规则。
  3. 遍历ArrayList,打印输出

大家也可以尝试使用TreeMap来解决。

Java代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String s;
        // 注意 hasNext 和 hasNextLine 的区别
        while ((s = bf.readLine())!=null) { // 注意 while 处理多个 case
            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);//统计字符出现次数
            }
            ArrayList<Map.Entry> list=new ArrayList<>(map.entrySet());//把map放入list中。
            Collections.sort(list, new Comparator<Map.Entry>() {
                @Override
                public int compare(Map.Entry o1, Map.Entry o2) {
                    if(o1.getValue()!=o2.getValue()){//如果字符出现次数不同 按照出现次数从高到底
                        return (int)(o2.getValue())-(int)(o1.getValue());
                    }else{//若次数相同则对比ASCII的大小 按照升序排列
                        return (char)(o1.getKey())-(char)(o2.getKey());
                    }
                }
            });
            //最后打印输出
            for (Map.Entry entry : list) {
                System.out.print(entry.getKey());
            }
            System.out.println();//换行 多组输入
        }
    }

}

复杂度分析

  • 时间复杂度:O(nlog(n))O(n * log(n))主要是排序的时间复杂度
  • 空间复杂度:O(n)O(n),一个ArrayList临时数组。