@@ -75,91 +75,173 @@ tags:
75
75
76
76
### 方法一:自定义排序
77
77
78
+ 我们可以使用自定义排序的方法,将日志分为两类:字母日志和数字日志。
79
+
80
+ 对于字母日志,我们需要按照题目要求进行排序,即先按内容排序,再按标识符排序。
81
+
82
+ 对于数字日志,我们只需要保留原来的相对顺序。
83
+
84
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是日志的数量。
85
+
78
86
<!-- tabs:start -->
79
87
80
88
#### Python3
81
89
82
90
``` python
83
91
class Solution :
84
92
def reorderLogFiles (self , logs : List[str ]) -> List[str ]:
85
- def cmp ( x ):
86
- a, b = x .split(' ' , 1 )
87
- return (0 , b, a ) if b [0 ].isalpha() else (1 ,)
93
+ def f ( log : str ):
94
+ id_, rest = log .split(" " , 1 )
95
+ return (0 , rest, id_ ) if rest [0 ].isalpha() else (1 ,)
88
96
89
- return sorted (logs, key = cmp )
97
+ return sorted (logs, key = f )
90
98
```
91
99
92
100
#### Java
93
101
94
102
``` java
95
103
class Solution {
96
104
public String [] reorderLogFiles (String [] logs ) {
97
- Arrays . sort(logs, this :: cmp);
105
+ Arrays . sort(logs, (log1, log2) - > {
106
+ String [] split1 = log1. split(" " , 2 );
107
+ String [] split2 = log2. split(" " , 2 );
108
+
109
+ boolean isLetter1 = Character . isLetter(split1[1 ]. charAt(0 ));
110
+ boolean isLetter2 = Character . isLetter(split2[1 ]. charAt(0 ));
111
+
112
+ if (isLetter1 && isLetter2) {
113
+ int cmp = split1[1 ]. compareTo(split2[1 ]);
114
+ if (cmp != 0 ) {
115
+ return cmp;
116
+ }
117
+ return split1[0 ]. compareTo(split2[0 ]);
118
+ }
119
+
120
+ return isLetter1 ? - 1 : (isLetter2 ? 1 : 0 );
121
+ });
122
+
98
123
return logs;
99
124
}
125
+ }
126
+ ```
100
127
101
- private int cmp (String a , String b ) {
102
- String [] t1 = a. split(" " , 2 );
103
- String [] t2 = b. split(" " , 2 );
104
- boolean d1 = Character . isDigit(t1[1 ]. charAt(0 ));
105
- boolean d2 = Character . isDigit(t2[1 ]. charAt(0 ));
106
- if (! d1 && ! d2) {
107
- int v = t1[1 ]. compareTo(t2[1 ]);
108
- return v == 0 ? t1[0 ]. compareTo(t2[0 ]) : v;
109
- }
110
- if (d1 && d2) {
111
- return 0 ;
112
- }
113
- return d1 ? 1 : - 1 ;
128
+ #### C++
129
+
130
+ ``` cpp
131
+ class Solution {
132
+ public:
133
+ vector<string > reorderLogFiles(vector<string >& logs) {
134
+ stable_sort(logs.begin(), logs.end(), [ ] (const string& log1, const string& log2) {
135
+ int idx1 = log1.find(' ');
136
+ int idx2 = log2.find(' ');
137
+ string id1 = log1.substr(0, idx1);
138
+ string id2 = log2.substr(0, idx2);
139
+ string content1 = log1.substr(idx1 + 1);
140
+ string content2 = log2.substr(idx2 + 1);
141
+
142
+ bool isLetter1 = isalpha(content1[0]);
143
+ bool isLetter2 = isalpha(content2[0]);
144
+
145
+ if (isLetter1 && isLetter2) {
146
+ if (content1 != content2) {
147
+ return content1 < content2;
148
+ }
149
+ return id1 < id2;
150
+ }
151
+
152
+ return isLetter1 > isLetter2;
153
+ });
154
+
155
+ return logs;
114
156
}
157
+ };
158
+ ```
159
+
160
+ #### Go
161
+
162
+ ``` go
163
+ func reorderLogFiles (logs []string ) []string {
164
+ sort.SliceStable (logs, func (i, j int ) bool {
165
+ log1 , log2 := logs[i], logs[j]
166
+ idx1 := strings.IndexByte (log1, ' ' )
167
+ idx2 := strings.IndexByte (log2, ' ' )
168
+ id1 , content1 := log1[:idx1], log1[idx1+1 :]
169
+ id2 , content2 := log2[:idx2], log2[idx2+1 :]
170
+
171
+ isLetter1 := ' a' <= content1[0 ] && content1[0 ] <= ' z'
172
+ isLetter2 := ' a' <= content2[0 ] && content2[0 ] <= ' z'
173
+
174
+ if isLetter1 && isLetter2 {
175
+ if content1 != content2 {
176
+ return content1 < content2
177
+ }
178
+ return id1 < id2
179
+ }
180
+
181
+ return isLetter1 && !isLetter2
182
+ })
183
+
184
+ return logs
115
185
}
116
186
```
117
187
118
188
#### TypeScript
119
189
120
190
``` ts
121
191
function reorderLogFiles(logs : string []): string [] {
122
- const isDigit = (c : string ) => c >= ' 0' && c <= ' 9' ;
123
- return logs .sort ((a , b ) => {
124
- const end1 = a [a .length - 1 ];
125
- const end2 = b [b .length - 1 ];
126
- if (isDigit (end1 ) && isDigit (end2 )) {
127
- return 0 ;
128
- }
129
- if (isDigit (end1 )) {
130
- return 1 ;
131
- }
132
- if (isDigit (end2 )) {
133
- return - 1 ;
134
- }
135
- const content1 = a .split (' ' ).slice (1 ).join (' ' );
136
- const content2 = b .split (' ' ).slice (1 ).join (' ' );
137
- if (content1 === content2 ) {
138
- return a < b ? - 1 : 1 ;
192
+ return logs .sort ((log1 , log2 ) => {
193
+ const [id1, content1] = log1 .split (/ (. + )/ );
194
+ const [id2, content2] = log2 .split (/ (. + )/ );
195
+
196
+ const isLetter1 = isNaN (Number (content1 [0 ]));
197
+ const isLetter2 = isNaN (Number (content2 [0 ]));
198
+
199
+ if (isLetter1 && isLetter2 ) {
200
+ const cmp = content1 .localeCompare (content2 );
201
+ if (cmp !== 0 ) {
202
+ return cmp ;
203
+ }
204
+ return id1 .localeCompare (id2 );
139
205
}
140
- return content1 < content2 ? - 1 : 1 ;
206
+
207
+ return isLetter1 ? - 1 : isLetter2 ? 1 : 0 ;
141
208
});
142
209
}
143
210
```
144
211
145
212
#### Rust
146
213
147
214
``` rust
215
+ use std :: cmp :: Ordering ;
216
+
148
217
impl Solution {
149
- pub fn reorder_log_files (mut logs : Vec <String >) -> Vec <String > {
150
- logs . sort_by (| s1 , s2 | {
151
- let (start1 , content1 ) = s1 . split_once (' ' ). unwrap ();
152
- let (start2 , content2 ) = s2 . split_once (' ' ). unwrap ();
153
- match (
154
- content1 . chars (). nth (0 ). unwrap (). is_digit (10 ),
155
- content2 . chars (). nth (0 ). unwrap (). is_digit (10 ),
156
- ) {
157
- (true , true ) => std :: cmp :: Ordering :: Equal ,
158
- (true , false ) => std :: cmp :: Ordering :: Greater ,
159
- (false , true ) => std :: cmp :: Ordering :: Less ,
160
- (false , false ) => content1 . cmp (& content2 ). then (start1 . cmp (& start2 )),
218
+ pub fn reorder_log_files (logs : Vec <String >) -> Vec <String > {
219
+ let mut logs = logs ;
220
+
221
+ logs . sort_by (| log1 , log2 | {
222
+ let split1 : Vec <& str > = log1 . splitn (2 , ' ' ). collect ();
223
+ let split2 : Vec <& str > = log2 . splitn (2 , ' ' ). collect ();
224
+
225
+ let is_letter1 = split1 [1 ]. chars (). next (). unwrap (). is_alphabetic ();
226
+ let is_letter2 = split2 [1 ]. chars (). next (). unwrap (). is_alphabetic ();
227
+
228
+ if is_letter1 && is_letter2 {
229
+ let cmp = split1 [1 ]. cmp (split2 [1 ]);
230
+ if cmp != Ordering :: Equal {
231
+ return cmp ;
232
+ }
233
+ return split1 [0 ]. cmp (split2 [0 ]);
234
+ }
235
+
236
+ if is_letter1 {
237
+ Ordering :: Less
238
+ } else if is_letter2 {
239
+ Ordering :: Greater
240
+ } else {
241
+ Ordering :: Equal
161
242
}
162
243
});
244
+
163
245
logs
164
246
}
165
247
}
0 commit comments