52
52
53
53
<!-- 这里可写通用的实现逻辑 -->
54
54
55
- “计数器 + 桶”实现。其中,计数器统计字符串中每个字符出现的次数。而对于桶,第 i 个位置存放出现次数为 i 的所有字符。
55
+ ** 方法一:哈希表 + 排序**
56
+
57
+ 我们用哈希表 $cnt$ 统计字符串 $s$ 中每个字符出现的次数,然后将 $cnt$ 中的键值对按照出现次数降序排序,最后按照排序后的顺序拼接字符串即可。
58
+
59
+ 时间复杂度 $O(n + k \times \log k)$,空间复杂度 $O(n + k)$,其中 $n$ 为字符串 $s$ 的长度,而 $k$ 为不同字符的个数。
56
60
57
61
<!-- tabs:start -->
58
62
63
67
``` python
64
68
class Solution :
65
69
def frequencySort (self , s : str ) -> str :
66
- counter = Counter(s)
67
- buckets = defaultdict(list )
68
- for c, freq in counter.items():
69
- buckets[freq].append(c)
70
- res = []
71
- for i in range (len (s), - 1 , - 1 ):
72
- if buckets[i]:
73
- for c in buckets[i]:
74
- res.append(c * i)
75
- return ' ' .join(res)
70
+ cnt = Counter(s)
71
+ return ' ' .join(c * v for c, v in sorted (cnt.items(), key = lambda x : - x[1 ]))
76
72
```
77
73
78
74
### ** Java**
@@ -82,74 +78,84 @@ class Solution:
82
78
``` java
83
79
class Solution {
84
80
public String frequencySort (String s ) {
85
- Map<Character , Integer > counter = new HashMap<> ();
86
- for (char c : s. toCharArray()) {
87
- counter. put(c, counter. getOrDefault(c, 0 ) + 1 );
88
- }
89
- List<Character > [] buckets = new List [s. length() + 1 ];
90
- for (Map . Entry<Character , Integer > entry : counter. entrySet()) {
91
- char c = entry. getKey();
92
- int freq = entry. getValue();
93
- if (buckets[freq] == null ) {
94
- buckets[freq] = new ArrayList<> ();
95
- }
96
- buckets[freq]. add(c);
81
+ Map<Character , Integer > cnt = new HashMap<> (52 );
82
+ for (int i = 0 ; i < s. length(); ++ i) {
83
+ cnt. merge(s. charAt(i), 1 , Integer :: sum);
97
84
}
98
- StringBuilder sb = new StringBuilder ();
99
- for (int i = s. length(); i >= 0 ; -- i) {
100
- if (buckets[i] != null ) {
101
- for (char c : buckets[i]) {
102
- for (int j = 0 ; j < i; ++ j) {
103
- sb. append(c);
104
- }
105
- }
85
+ List<Character > cs = new ArrayList<> (cnt. keySet());
86
+ cs. sort((a, b) - > cnt. get(b) - cnt. get(a));
87
+ StringBuilder ans = new StringBuilder ();
88
+ for (char c : cs) {
89
+ for (int v = cnt. get(c); v > 0 ; -- v) {
90
+ ans. append(c);
106
91
}
107
92
}
108
- return sb . toString();
93
+ return ans . toString();
109
94
}
110
95
}
111
96
```
112
97
113
- ### ** Go**
98
+ ### ** C++**
99
+
100
+ ``` cpp
101
+ class Solution {
102
+ public:
103
+ string frequencySort(string s) {
104
+ unordered_map<char, int> cnt;
105
+ for (char& c : s) {
106
+ ++cnt[ c] ;
107
+ }
108
+ vector<char > cs;
109
+ for (auto& [ c, _ ] : cnt) {
110
+ cs.push_back(c);
111
+ }
112
+ sort(cs.begin(), cs.end(), [ &] (char& a, char& b) {
113
+ return cnt[ a] > cnt[ b] ;
114
+ });
115
+ string ans;
116
+ for (char& c : cs) {
117
+ ans += string(cnt[ c] , c);
118
+ }
119
+ return ans;
120
+ }
121
+ };
122
+ ```
114
123
115
- 用结构体排序进行模拟
124
+ ### **Go**
116
125
117
126
```go
118
- type pair struct {
119
- b byte
120
- cnt int
121
- }
122
-
123
127
func frequencySort(s string) string {
124
- freq := make ( map [byte ]int )
125
- for _ , r := range s {
126
- freq[ byte (r) ]++
128
+ cnt := map[byte]int{}
129
+ for i := range s {
130
+ cnt[s[i] ]++
127
131
}
128
- a := make ([]pair , 0 )
129
- for k , v := range freq {
130
- a = append (a, pair{b: k, cnt: v} )
132
+ cs := make([]byte , 0, len(s) )
133
+ for c := range cnt {
134
+ cs = append(cs, c )
131
135
}
132
- sort.Slice (a , func (i, j int ) bool { return a[i]. cnt > a[j]. cnt })
133
- var sb strings. Builder
134
- for _ , p := range a {
135
- sb. Write ( bytes.Repeat ([]byte {p. b }, p. cnt ) )
136
+ sort.Slice(cs , func(i, j int) bool { return cnt[cs[i]] > cnt[cs[j]] })
137
+ ans := make([]byte, 0, len(s))
138
+ for _, c := range cs {
139
+ ans = append(ans, bytes.Repeat([]byte{c }, cnt[c])... )
136
140
}
137
- return sb. String ( )
141
+ return string(ans )
138
142
}
139
143
```
140
144
141
145
### ** TypeScript**
142
146
143
147
``` ts
144
148
function frequencySort(s : string ): string {
145
- const map = new Map <string , number >();
149
+ const cnt : Map <string , number > = new Map ();
146
150
for (const c of s ) {
147
- map .set (c , (map .get (c ) ?? 0 ) + 1 );
151
+ cnt .set (c , (cnt .get (c ) || 0 ) + 1 );
152
+ }
153
+ const cs = Array .from (cnt .keys ()).sort ((a , b ) => cnt .get (b )! - cnt .get (a )! );
154
+ const ans: string [] = [];
155
+ for (const c of cs ) {
156
+ ans .push (c .repeat (cnt .get (c )! ));
148
157
}
149
- return [... map .entries ()]
150
- .sort ((a , b ) => b [1 ] - a [1 ])
151
- .map (([k , v ]) => k .padStart (v , k ))
152
- .join (' ' );
158
+ return ans .join (' ' );
153
159
}
154
160
```
155
161
@@ -159,13 +165,13 @@ function frequencySort(s: string): string {
159
165
use std :: collections :: HashMap ;
160
166
impl Solution {
161
167
pub fn frequency_sort (s : String ) -> String {
162
- let mut map = HashMap :: new ();
168
+ let mut cnt = HashMap :: new ();
163
169
for c in s . chars () {
164
- map . insert (c , map . get (& c ). unwrap_or (& 0 ) + 1 );
170
+ cnt . insert (c , cnt . get (& c ). unwrap_or (& 0 ) + 1 );
165
171
}
166
- let mut arr = map . into_iter (). collect :: <Vec <(char , i32 )>>();
167
- arr . sort_unstable_by (| (_ , a ), (_ , b )| b . cmp (& a ));
168
- arr . into_iter ()
172
+ let mut cs = cnt . into_iter (). collect :: <Vec <(char , i32 )>>();
173
+ cs . sort_unstable_by (| (_ , a ), (_ , b )| b . cmp (& a ));
174
+ cs . into_iter ()
169
175
. map (| (c , v )| vec! [c ; v as usize ]. into_iter (). collect :: <String >())
170
176
. collect ()
171
177
}
0 commit comments