Skip to content

Commit 6ef2380

Browse files
committedApr 8, 2023
feat: add solutions to lc problem: No.0451
No.0451.Sort Characters By Frequency
1 parent dcdaeeb commit 6ef2380

File tree

8 files changed

+187
-180
lines changed

8 files changed

+187
-180
lines changed
 

‎solution/0400-0499/0451.Sort Characters By Frequency/README.md

+67-61
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@
5252

5353
<!-- 这里可写通用的实现逻辑 -->
5454

55-
“计数器 + 桶”实现。其中,计数器统计字符串中每个字符出现的次数。而对于桶,第 i 个位置存放出现次数为 i 的所有字符。
55+
**方法一:哈希表 + 排序**
56+
57+
我们用哈希表 $cnt$ 统计字符串 $s$ 中每个字符出现的次数,然后将 $cnt$ 中的键值对按照出现次数降序排序,最后按照排序后的顺序拼接字符串即可。
58+
59+
时间复杂度 $O(n + k \times \log k)$,空间复杂度 $O(n + k)$,其中 $n$ 为字符串 $s$ 的长度,而 $k$ 为不同字符的个数。
5660

5761
<!-- tabs:start -->
5862

@@ -63,16 +67,8 @@
6367
```python
6468
class Solution:
6569
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]))
7672
```
7773

7874
### **Java**
@@ -82,74 +78,84 @@ class Solution:
8278
```java
8379
class Solution {
8480
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);
9784
}
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);
10691
}
10792
}
108-
return sb.toString();
93+
return ans.toString();
10994
}
11095
}
11196
```
11297

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+
```
114123
115-
用结构体排序进行模拟
124+
### **Go**
116125
117126
```go
118-
type pair struct {
119-
b byte
120-
cnt int
121-
}
122-
123127
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]]++
127131
}
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)
131135
}
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])...)
136140
}
137-
return sb.String()
141+
return string(ans)
138142
}
139143
```
140144

141145
### **TypeScript**
142146

143147
```ts
144148
function frequencySort(s: string): string {
145-
const map = new Map<string, number>();
149+
const cnt: Map<string, number> = new Map();
146150
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)!));
148157
}
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('');
153159
}
154160
```
155161

@@ -159,13 +165,13 @@ function frequencySort(s: string): string {
159165
use std::collections::HashMap;
160166
impl Solution {
161167
pub fn frequency_sort(s: String) -> String {
162-
let mut map = HashMap::new();
168+
let mut cnt = HashMap::new();
163169
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);
165171
}
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()
169175
.map(|(c, v)| vec![c; v as usize].into_iter().collect::<String>())
170176
.collect()
171177
}

‎solution/0400-0499/0451.Sort Characters By Frequency/README_EN.md

+62-60
Original file line numberDiff line numberDiff line change
@@ -53,91 +53,93 @@ Note that &#39;A&#39; and &#39;a&#39; are treated as two different characters.
5353
```python
5454
class Solution:
5555
def frequencySort(self, s: str) -> str:
56-
counter = Counter(s)
57-
buckets = defaultdict(list)
58-
for c, freq in counter.items():
59-
buckets[freq].append(c)
60-
res = []
61-
for i in range(len(s), -1, -1):
62-
if buckets[i]:
63-
for c in buckets[i]:
64-
res.append(c * i)
65-
return ''.join(res)
56+
cnt = Counter(s)
57+
return ''.join(c * v for c, v in sorted(cnt.items(), key=lambda x: -x[1]))
6658
```
6759

6860
### **Java**
6961

7062
```java
7163
class Solution {
7264
public String frequencySort(String s) {
73-
Map<Character, Integer> counter = new HashMap<>();
74-
for (char c : s.toCharArray()) {
75-
counter.put(c, counter.getOrDefault(c, 0) + 1);
65+
Map<Character, Integer> cnt = new HashMap<>(52);
66+
for (int i = 0; i < s.length(); ++i) {
67+
cnt.merge(s.charAt(i), 1, Integer::sum);
7668
}
77-
List<Character>[] buckets = new List[s.length() + 1];
78-
for (Map.Entry<Character, Integer> entry : counter.entrySet()) {
79-
char c = entry.getKey();
80-
int freq = entry.getValue();
81-
if (buckets[freq] == null) {
82-
buckets[freq] = new ArrayList<>();
69+
List<Character> cs = new ArrayList<>(cnt.keySet());
70+
cs.sort((a, b) -> cnt.get(b) - cnt.get(a));
71+
StringBuilder ans = new StringBuilder();
72+
for (char c : cs) {
73+
for (int v = cnt.get(c); v > 0; --v) {
74+
ans.append(c);
8375
}
84-
buckets[freq].add(c);
8576
}
86-
StringBuilder sb = new StringBuilder();
87-
for (int i = s.length(); i >= 0; --i) {
88-
if (buckets[i] != null) {
89-
for (char c : buckets[i]) {
90-
for (int j = 0; j < i; ++j) {
91-
sb.append(c);
92-
}
93-
}
94-
}
95-
}
96-
return sb.toString();
77+
return ans.toString();
9778
}
9879
}
9980
```
10081

101-
### **Go**
82+
### **C++**
83+
84+
```cpp
85+
class Solution {
86+
public:
87+
string frequencySort(string s) {
88+
unordered_map<char, int> cnt;
89+
for (char& c : s) {
90+
++cnt[c];
91+
}
92+
vector<char> cs;
93+
for (auto& [c, _] : cnt) {
94+
cs.push_back(c);
95+
}
96+
sort(cs.begin(), cs.end(), [&](char& a, char& b) {
97+
return cnt[a] > cnt[b];
98+
});
99+
string ans;
100+
for (char& c : cs) {
101+
ans += string(cnt[c], c);
102+
}
103+
return ans;
104+
}
105+
};
106+
```
102107
103-
Simulation with structure sorting.
108+
### **Go**
104109
105110
```go
106-
type pair struct {
107-
b byte
108-
cnt int
109-
}
110-
111111
func frequencySort(s string) string {
112-
freq := make(map[byte]int)
113-
for _, r := range s {
114-
freq[byte(r)]++
112+
cnt := map[byte]int{}
113+
for i := range s {
114+
cnt[s[i]]++
115115
}
116-
a := make([]pair, 0)
117-
for k, v := range freq {
118-
a = append(a, pair{b: k, cnt: v})
116+
cs := make([]byte, 0, len(s))
117+
for c := range cnt {
118+
cs = append(cs, c)
119119
}
120-
sort.Slice(a, func(i, j int) bool { return a[i].cnt > a[j].cnt })
121-
var sb strings.Builder
122-
for _, p := range a {
123-
sb.Write(bytes.Repeat([]byte{p.b}, p.cnt))
120+
sort.Slice(cs, func(i, j int) bool { return cnt[cs[i]] > cnt[cs[j]] })
121+
ans := make([]byte, 0, len(s))
122+
for _, c := range cs {
123+
ans = append(ans, bytes.Repeat([]byte{c}, cnt[c])...)
124124
}
125-
return sb.String()
125+
return string(ans)
126126
}
127127
```
128128

129129
### **TypeScript**
130130

131131
```ts
132132
function frequencySort(s: string): string {
133-
const map = new Map<string, number>();
133+
const cnt: Map<string, number> = new Map();
134134
for (const c of s) {
135-
map.set(c, (map.get(c) ?? 0) + 1);
135+
cnt.set(c, (cnt.get(c) || 0) + 1);
136+
}
137+
const cs = Array.from(cnt.keys()).sort((a, b) => cnt.get(b)! - cnt.get(a)!);
138+
const ans: string[] = [];
139+
for (const c of cs) {
140+
ans.push(c.repeat(cnt.get(c)!));
136141
}
137-
return [...map.entries()]
138-
.sort((a, b) => b[1] - a[1])
139-
.map(([k, v]) => k.padStart(v, k))
140-
.join('');
142+
return ans.join('');
141143
}
142144
```
143145

@@ -147,13 +149,13 @@ function frequencySort(s: string): string {
147149
use std::collections::HashMap;
148150
impl Solution {
149151
pub fn frequency_sort(s: String) -> String {
150-
let mut map = HashMap::new();
152+
let mut cnt = HashMap::new();
151153
for c in s.chars() {
152-
map.insert(c, map.get(&c).unwrap_or(&0) + 1);
154+
cnt.insert(c, cnt.get(&c).unwrap_or(&0) + 1);
153155
}
154-
let mut arr = map.into_iter().collect::<Vec<(char, i32)>>();
155-
arr.sort_unstable_by(|(_, a), (_, b)| b.cmp(&a));
156-
arr.into_iter()
156+
let mut cs = cnt.into_iter().collect::<Vec<(char, i32)>>();
157+
cs.sort_unstable_by(|(_, a), (_, b)| b.cmp(&a));
158+
cs.into_iter()
157159
.map(|(c, v)| vec![c; v as usize].into_iter().collect::<String>())
158160
.collect()
159161
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public:
3+
string frequencySort(string s) {
4+
unordered_map<char, int> cnt;
5+
for (char& c : s) {
6+
++cnt[c];
7+
}
8+
vector<char> cs;
9+
for (auto& [c, _] : cnt) {
10+
cs.push_back(c);
11+
}
12+
sort(cs.begin(), cs.end(), [&](char& a, char& b) {
13+
return cnt[a] > cnt[b];
14+
});
15+
string ans;
16+
for (char& c : cs) {
17+
ans += string(cnt[c], c);
18+
}
19+
return ans;
20+
}
21+
};
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
1-
type pair struct {
2-
b byte
3-
cnt int
4-
}
5-
61
func frequencySort(s string) string {
7-
freq := make(map[byte]int)
8-
for _, r := range s {
9-
freq[byte(r)]++
2+
cnt := map[byte]int{}
3+
for i := range s {
4+
cnt[s[i]]++
105
}
11-
a := make([]pair, 0)
12-
for k, v := range freq {
13-
a = append(a, pair{b: k, cnt: v})
6+
cs := make([]byte, 0, len(s))
7+
for c := range cnt {
8+
cs = append(cs, c)
149
}
15-
sort.Slice(a, func(i, j int) bool { return a[i].cnt > a[j].cnt })
16-
var sb strings.Builder
17-
for _, p := range a {
18-
sb.Write(bytes.Repeat([]byte{p.b}, p.cnt))
10+
sort.Slice(cs, func(i, j int) bool { return cnt[cs[i]] > cnt[cs[j]] })
11+
ans := make([]byte, 0, len(s))
12+
for _, c := range cs {
13+
ans = append(ans, bytes.Repeat([]byte{c}, cnt[c])...)
1914
}
20-
return sb.String()
21-
}
15+
return string(ans)
16+
}
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,17 @@
11
class Solution {
22
public String frequencySort(String s) {
3-
Map<Character, Integer> counter = new HashMap<>();
4-
for (char c : s.toCharArray()) {
5-
counter.put(c, counter.getOrDefault(c, 0) + 1);
3+
Map<Character, Integer> cnt = new HashMap<>(52);
4+
for (int i = 0; i < s.length(); ++i) {
5+
cnt.merge(s.charAt(i), 1, Integer::sum);
66
}
7-
List<Character>[] buckets = new List[s.length() + 1];
8-
for (Map.Entry<Character, Integer> entry : counter.entrySet()) {
9-
char c = entry.getKey();
10-
int freq = entry.getValue();
11-
if (buckets[freq] == null) {
12-
buckets[freq] = new ArrayList<>();
7+
List<Character> cs = new ArrayList<>(cnt.keySet());
8+
cs.sort((a, b) -> cnt.get(b) - cnt.get(a));
9+
StringBuilder ans = new StringBuilder();
10+
for (char c : cs) {
11+
for (int v = cnt.get(c); v > 0; --v) {
12+
ans.append(c);
1313
}
14-
buckets[freq].add(c);
1514
}
16-
StringBuilder sb = new StringBuilder();
17-
for (int i = s.length(); i >= 0; --i) {
18-
if (buckets[i] != null) {
19-
for (char c : buckets[i]) {
20-
for (int j = 0; j < i; ++j) {
21-
sb.append(c);
22-
}
23-
}
24-
}
25-
}
26-
return sb.toString();
15+
return ans.toString();
2716
}
2817
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
class Solution:
22
def frequencySort(self, s: str) -> str:
3-
counter = Counter(s)
4-
buckets = defaultdict(list)
5-
for c, freq in counter.items():
6-
buckets[freq].append(c)
7-
res = []
8-
for i in range(len(s), -1, -1):
9-
if buckets[i]:
10-
for c in buckets[i]:
11-
res.append(c * i)
12-
return ''.join(res)
3+
cnt = Counter(s)
4+
return ''.join(c * v for c, v in sorted(cnt.items(), key=lambda x: -x[1]))

‎solution/0400-0499/0451.Sort Characters By Frequency/Solution.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::collections::HashMap;
22
impl Solution {
33
pub fn frequency_sort(s: String) -> String {
4-
let mut map = HashMap::new();
4+
let mut cnt = HashMap::new();
55
for c in s.chars() {
6-
map.insert(c, map.get(&c).unwrap_or(&0) + 1);
6+
cnt.insert(c, cnt.get(&c).unwrap_or(&0) + 1);
77
}
8-
let mut arr = map.into_iter().collect::<Vec<(char, i32)>>();
9-
arr.sort_unstable_by(|(_, a), (_, b)| b.cmp(&a));
10-
arr.into_iter()
8+
let mut cs = cnt.into_iter().collect::<Vec<(char, i32)>>();
9+
cs.sort_unstable_by(|(_, a), (_, b)| b.cmp(&a));
10+
cs.into_iter()
1111
.map(|(c, v)| vec![c; v as usize].into_iter().collect::<String>())
1212
.collect()
1313
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
function frequencySort(s: string): string {
2-
const map = new Map<string, number>();
2+
const cnt: Map<string, number> = new Map();
33
for (const c of s) {
4-
map.set(c, (map.get(c) ?? 0) + 1);
4+
cnt.set(c, (cnt.get(c) || 0) + 1);
55
}
6-
return [...map.entries()]
7-
.sort((a, b) => b[1] - a[1])
8-
.map(([k, v]) => k.padStart(v, k))
9-
.join('');
6+
const cs = Array.from(cnt.keys()).sort((a, b) => cnt.get(b)! - cnt.get(a)!);
7+
const ans: string[] = [];
8+
for (const c of cs) {
9+
ans.push(c.repeat(cnt.get(c)!));
10+
}
11+
return ans.join('');
1012
}

0 commit comments

Comments
 (0)
Please sign in to comment.