2021.05.15按照字符出现的频率排序

本文介绍了一种基于字符出现频率对字符串进行排序的方法。提供了三种不同的实现思路:通过频率排序、迭代寻找最大频率以及桶排序。这些方法适用于需要对字符频率进行高效处理的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2021.05.15按照字符出现的频率排序

(题目来源:https://leetcode-cn.com/problems/sort-characters-by-frequency/ )

注意

本题较为简单,但是设计了桶排序等知识,还是做下笔记。

思路

思路1:通过频率进行排序

	public String frequencySort(String s) {
		if(s.length() == 0) return "";
		char[] chs = s.toCharArray();
		int[][] chcnt = new int[126-35+1][2];
		for(int i = 0; i < chcnt.length; i++) chcnt[i][0] = i;
		for(int i = 0; i < chs.length; i++) {
			chcnt[chs[i]-35][1]++;
		}
		Arrays.sort(chcnt, new Comparator<int[]>() {
			public int compare(int[] t1, int[] t2) {
				return t2[1]-t1[1];
			}
		});
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < chcnt.length; i++) {
			char ch = (char)(35+chcnt[i][0]);
			for(int j = 0; j < chcnt[i][1]; j++) {
				sb.append(ch);
			}
		}
		return sb.toString();
	}

思路2:不用排序,迭代找最大频率(性能最好)

	public String frequencySort(String s) {
		if(s.length() == 0) return "";
		char[] chs = s.toCharArray();
		int[] cnt = new int[256];
		for(int i = 0; i < chs.length; i++) cnt[chs[i]]++;
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < chs.length; i++) {
			int max = 0, maxInd = 0; 
			for(int j = 0; j < cnt.length; j++) {
				if(max < cnt[j]) {
					max = cnt[j];
					maxInd = j;
				}
			}
			cnt[maxInd] = 0; //找到最大频率后将去归零
			for(int k = 0; k < max; k++) sb.append((char)maxInd);
			i += max-1;
		}
		return sb.toString();
	}

思路3:桶排序

思想:出现频率为i的放入第i个桶

	public String frequencySort2(String s) {
		if(s.length() == 0) return "";
		Map<Character, Integer> map = new HashMap<Character, Integer>();
		char[] chs = s.toCharArray();
		for(int i = 0; i < chs.length; i++) 
			map.put(chs[i], map.getOrDefault(chs[i], 0)+1);
		//定义列表数组
		List<Character>[] buckets = new ArrayList[s.length()+1];
		for(char k: map.keySet()) {
			int v = map.get(k);
			if(buckets[v] == null) buckets[v] = new ArrayList<Character>();
			buckets[v].add(k);
		}
		int ind = 0;
		for(int i = buckets.length-1; i > 0; i--) { //找到第i个桶,桶里装的是有i个重复的字符
			if(buckets[i] == null) continue;
			for(int j = 0; j < buckets[i].size(); j++) { // 如果里面有j个字符,一样遍历
				char tmp = buckets[i].get(j);
				for(int k = 0; k < i; k++) {
					chs[ind++] = tmp;
				}
			}
		}
		return new String(chs);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值