@@ -75,91 +75,173 @@ tags:
7575
7676### 方法一:自定义排序
7777
78+ 我们可以使用自定义排序的方法,将日志分为两类:字母日志和数字日志。
79+
80+ 对于字母日志,我们需要按照题目要求进行排序,即先按内容排序,再按标识符排序。
81+
82+ 对于数字日志,我们只需要保留原来的相对顺序。
83+
84+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是日志的数量。
85+
7886<!-- tabs:start -->
7987
8088#### Python3
8189
8290``` python
8391class Solution :
8492 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 ,)
8896
89- return sorted (logs, key = cmp )
97+ return sorted (logs, key = f )
9098```
9199
92100#### Java
93101
94102``` java
95103class Solution {
96104 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+
98123 return logs;
99124 }
125+ }
126+ ```
100127
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;
114156 }
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
115185}
116186```
117187
118188#### TypeScript
119189
120190``` ts
121191function 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 );
139205 }
140- return content1 < content2 ? - 1 : 1 ;
206+
207+ return isLetter1 ? - 1 : isLetter2 ? 1 : 0 ;
141208 });
142209}
143210```
144211
145212#### Rust
146213
147214``` rust
215+ use std :: cmp :: Ordering ;
216+
148217impl 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
161242 }
162243 });
244+
163245 logs
164246 }
165247}
0 commit comments