451. Sort Characters By Frequency

Problem Description:

Given a string, sort it in decreasing order based on the frequency of characters.

Example 1:

Input:
"tree"

Output:
"eert"

Explanation:
'e' appears twice while 'r' and 't' both appear once.
So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer.

Example 2:

Input:
"cccaaa"

Output:
"cccaaa"

Explanation:
Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer.
Note that "cacaca" is incorrect, as the same characters must be together.

Example 3:

Input:
"Aabb"

Output:
"bbAa"

Explanation:
"bbaA" is also a valid answer, but "Aabb" is incorrect.
Note that 'A' and 'a' are treated as two different characters.

贴入代码及注释

char* frequencySort(char* s) {
    long int a[128][2]; //二维数组a[i][0]为ascii码,a[i][1]为该符号出现的次数
    int i,j,k;          //计数变量   
    int max[2]={0};     //max[0]存储出现次数最多的符号的次数,max[1]存储次数最多的符号
    int count = 0;      //计算字符串长度不含/0
    char* re;           //返回拼凑出的字符串指针

    for(i=0;i<128;i++){ //将128ascii码复制,并把对应技术单位赋空
    	a[i][0]=i;
    	a[i][1]=0;
	}
	i=0;
	while(*(s+count)!='\0'){        //将每个字符串源码取出
	    a[*(s+count)][1]++;         //将取出的字符串进行次数统计,且对应字符串值即为二维数组下标
	    count++;                    //循环次数也即字符串长度去除/0
	}
	re = (char*)malloc((count+1) * sizeof(char));//开辟返回字符串空间
	k = 0;                                       //返回数组计数器初始化
	for(i=0;i<128;i++){                         //类似选择排序每次选出最最大次数的符号并存入返回数组
		for(j=0;j<128;j++){
    	    if(a[j][1]>max[0]){
    	    	max[0] = a[j][1];
    	    	max[1] = j;
		    }
	    }
	    while( a[max[1]][1]--){                 //将对应字符的次数变换成相同字符填入返回数组
	    	*(re+k) = a[max[1]][0];
	    	k++;
		}
	    a[max[1]][1]=0;                        //次数赋空
	    max[1]=0;
	    max[0]=0;
	}
	*(re+k)='\0';
	return re;
}

该题目注意点:示例中仅有小写字幕a-z,实际题目意思为所有字符号,所以最好将128ascii全部包含在内。

算法步骤

1、将二维数组第一变量a[i][0]表示ascii码 第二变量a[i][1]表示为对应的次数即计数用

2、循环取出字符串字符,并以字符为下标直接对计数单元进行计数(好处比循环进行字符比较再进行计数少了O(n)复杂度

a[*(s+count)][1]++;  

3、用选择排序的思想不断取出次数最大的字符并存入新数组,此时为两层循环第一层为总共循环次数,第二层为选出最大次数字符



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值