给定一个字符串 s
,s
包含以空格分隔的若干个单词,请对 s
进行如下处理后输出:
请输出处理后的字符串,每个单词以一个空格分隔。
一行字符串,每个字符取值范围:[a-z, A-Z, 0-9]
以及空格" "
,字符串长度范围:[1, 1000]
重新排序后的字符串,每个单词间隔 1 个空格,且首尾无空格
This is an apple
an is This aelpp
My sister is in the house not in the yard
in in eht eht My is not adry ehosu eirsst
本题包含单词内和单词间的两种排序。先考虑单词内的排序,再考虑单词间的排序。
对于单词内的排序,需要对每个单词字母重新按字典序排序。所以我们在代码,对于lst
中的每一个单词word
:
list(word)
将字符串word
转化为列表sorted()
内置函数得到按照字典序排序的结果join()
方法将排序结果重新转化为字符串最后再使用列表推导式,可以得到每个单词内部进行排序后的新列表new_lst
。
new_lst = ["".join(sorted(list(word))) for word in lst]
对于单词间的排序,需要依次考虑三个因素:
对于单词出现频率这个因素,我们很容易想到直接使用哈希表计数器Counter()
来统计,即
cnt = Counter(new_lst)
而长度因素,可以很容易地使用len()
内置函数得到。
所以我们使用lambda
匿名函数来辅助new_lst
的排序,即
new_lst.sort(key = lambda x: (-cnt[x], len(x), x))
要注意,由于要求按照单词出现频率降序排列,我们应该以-cnt[x]
而不是cnt[x]
做为第一个排序依据。
最后,还需要把new_lst
的排序结果再一次使用join()
方法合并为字符串并输出。注意合并时要用空格" "
隔开每一个单词。
print(" ".join(new_lst))
时间复杂度:O(NlogN + Σ(MlogM))
。单词内、单词间进行排序的时间复杂度
空间复杂度:O(N)
。
Σ
表示求和,M
为每个单词的长度。
from collections import Counter
lst = input().split()
n = len(lst)
# 单词内的排序:
# 对于lst中的每一个单词word:
# 1. 用list(word)转化为列表
# 2. 用sorted()内置函数得到按照字典序排序的结果
# 3. 用join()方法将排序结果重新转化为字符串
# 再使用列表推导式,可以得到新的列表
new_lst = ["".join(sorted(list(word))) for word in lst]
# 单词间的排序:
# 用Counter()统计new_lst中各个单词的出现频率
cnt = Counter(new_lst)
# 使用lambda匿名函数,
# 1. 先按照出现次数即cnt[x]排序,为了实现从大到小排序,需要以-cnt[x]为依据
# 2. 再按照长度len(x)排序
# 3. 最后再按照字典序排序
new_lst.sort(key = lambda x: (-cnt[x], len(x), x))
# 最后使用join()方法,将排序后的列表转化为字符串输出,记得用" "隔开
print(" ".join(new_lst))
华为OD算法冲刺训练
华为OD算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
30+天陪伴式学习,20+直播课时,300+动画图解视频,200+LeetCode经典题,100+华为OD真题,还有简历修改与模拟面试将为你解锁
可查看链接 OD算法冲刺训练课程表 & OD真题汇总(持续更新)
绿色聊天软件戳 sheepvipvip了解更多