@@ -46,50 +46,39 @@ Tag : 「模拟」、「桶排序」、「哈希表」、「数组」、「优
46
46
注意'A'和'a'被认为是两种不同的字符。
47
47
```
48
48
49
+ 提示:
50
+ * $1 <= s.length <= 5 \times 10^5$
51
+ * ` s ` 由大小写英文字母和数字组成
52
+
49
53
---
50
54
51
55
### 数据结构 + 模拟
52
56
53
57
这是一道考察数据结构运用的模拟题。
54
58
55
59
具体做法如下:
56
-
57
60
1 . 先使用「哈希表」对词频进行统计;
58
61
2 . 遍历统计好词频的哈希表,将每个键值对以 ` {字符,词频} ` 的形式存储到「优先队列(堆)」中。并规定「优先队列(堆)」排序逻辑为:
59
62
* 如果 ` 词频 ` 不同,则按照 ` 词频 ` 倒序;
60
63
* 如果 ` 词频 ` 相同,则根据 ` 字符字典序 ` 升序(由于本题采用 Special Judge 机制,这个排序策略随意调整也可以。但通常为了确保排序逻辑满足「全序关系」,这个地方可以写正写反,但理论上不能不写,否则不能确保每次排序结果相同);
61
64
3 . 从「优先队列(堆)」依次弹出,构造答案。
62
65
63
- ![ image.png] ( https://pic.leetcode-cn.com/1625273052-MtkpTv-image.png )
64
-
65
66
代码:
66
67
``` Java
67
68
class Solution {
68
- class Node {
69
- char c;
70
- int v;
71
- Node (char _c , int _v ) {
72
- c = _c; v = _v;
73
- }
74
- }
75
69
public String frequencySort (String s ) {
76
70
char [] cs = s. toCharArray();
77
71
Map<Character , Integer > map = new HashMap<> ();
78
- for (char c : cs) {
79
- map. put(c, map. getOrDefault(c, 0 ) + 1 );
80
- }
81
- PriorityQueue<Node > q = new PriorityQueue<> ((a,b)- > {
82
- if (b. v != a. v) return b. v - a. v;
83
- return a. c - b. c;
72
+ for (char c : cs) map. put(c, map. getOrDefault(c, 0 ) + 1 );
73
+ PriorityQueue<int[]> q = new PriorityQueue<> ((a,b)- > {
74
+ return a[1 ] != b[1 ] ? b[1 ] - a[1 ] : a[0 ] - b[0 ];
84
75
});
85
- for (char c : map. keySet()) {
86
- q. add(new Node (c, map. get(c)));
87
- }
76
+ for (char c : map. keySet()) q. add(new int []{c, map. get(c)});
88
77
StringBuilder sb = new StringBuilder ();
89
78
while (! q. isEmpty()) {
90
- Node poll = q. poll();
91
- int k = poll. v ;
92
- while (k-- > 0 ) sb. append(poll . c );
79
+ int [] poll = q. poll();
80
+ int c = poll[ 0 ], k = poll[ 1 ] ;
81
+ while (k-- > 0 ) sb. append(( char )(c) );
93
82
}
94
83
return sb. toString();
95
84
}
@@ -106,8 +95,6 @@ class Solution {
106
95
107
96
具体的,利用 ASCII 字符集共 $128$ 位,预先建立一个大小为 $128$ 的数组,利用「桶排序」的思路替代「哈希表」和「优先队列(堆)」的作用。
108
97
109
- ![ image.png] ( https://pic.leetcode-cn.com/1625273079-aeNBlb-image.png )
110
-
111
98
代码:
112
99
``` Java
113
100
class Solution {
@@ -117,8 +104,7 @@ class Solution {
117
104
for (int i = 0 ; i < 128 ; i++ ) cnts[i][0 ] = i;
118
105
for (char c : cs) cnts[c][1 ]++ ;
119
106
Arrays . sort(cnts, (a, b)- > {
120
- if (a[1 ] != b[1 ]) return b[1 ] - a[1 ];
121
- return a[0 ] - b[0 ];
107
+ return a[1 ] != b[1 ] ? b[1 ] - a[1 ] : a[0 ] - b[0 ];
122
108
});
123
109
StringBuilder sb = new StringBuilder ();
124
110
for (int i = 0 ; i < 128 ; i++ ) {
@@ -130,7 +116,7 @@ class Solution {
130
116
}
131
117
}
132
118
```
133
- * 时间复杂度:令字符集的大小为 $C$。 复杂度为 $O(\max(n, C\log{C}))$
119
+ * 时间复杂度:令字符集的大小为 $C$, 复杂度为 $O(\max(n, C\log{C}))$
134
120
* 空间复杂度:$O(n + C + \log{C})$
135
121
136
122
---
0 commit comments