【新手友好】力扣451:从积木整理到字符排序的思维跃迁
题目深度解读
题目要求将字符串中的字符按出现频率降序排列,相同频率的字符无需保持原顺序。例如:
输入tree→输出eert(e出现2次,t和r各1次)输入cccaaa→输出cccaaa或aaaccc
关键点说明:
ASCII字符共128个(0-127),因此使用长度为128的数组足够不需要保持同频字符的原顺序,简化了排序逻辑
生活场景类比
想象整理一箱彩色积木:
1.统计阶段:把不同颜色的积木分类堆放(类似统计字符频率)
2.排序阶段:先搬数量最多的积木堆(如红色积木20个),再搬次多的(蓝色15个)...
3.组装阶段:按数量顺序把积木排成新队列
解题步骤拆解
频率统计:创建大小为128的数组,统计每个ASCII字符出现次数最大值
查找:每次遍历数组找到当前最大频率的字符
字符串构建:将该字符重复其频率次数追加到结果
消除已处理:将该字符频率置零防止重复处理
循环终止:当结果字符串长度等于原字符串时停止
注意事项
数组初始化必须清零,否则会有随机值
内层循环的终止条件是i128(覆盖所有ASCII字符)
时间复杂度O(n+k2),其中k是字符集大小(本题k=128)
代码实现(含注释)
classSolution{
public:
intbocket[128]={0};//ASCII码频率统计桶
stringfrequencySort(strings){
//统计阶段
for(inti=0;is.size();i++){
bocket[s[i]]++;//每个字符对应ASCII码位置的计数+1
}
strings1=;//结果字符串
//构建阶段
while(s1.size()s.size()){
intmaxidx=0;//当前最大频率字符的ASCII码
//查找阶段
for(inti=1;i128;i++){
if(bocket[i]bocket[maxidx]){
maxidx=i;//更新最大值下标
}
}
//拼接阶段
for(inti=0;ibocket[maxidx];i++){
s1+=maxidx;//按频率追加字符
}
bocket[maxidx]=0;//已处理标记
}
returns1;
}
};
分析
直观体现统计-查找-构建过程,适合教学演示,完美展示了如何用基础数组解决频率统计问题。