Skip to content

Commit df42635

Browse files
committed
feat: leetcode 937
1 parent 6282849 commit df42635

File tree

8 files changed

+193
-1
lines changed

8 files changed

+193
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<p align="center">
44
<!-- TOPICS COUNT START -->
5-
<img src="https://img.shields.io/badge/-进度:352-green" alt="进度:352">
5+
<img src="https://img.shields.io/badge/-进度:353-green" alt="进度:353">
66
<!-- TOPICS COUNT END -->
77
<a href="./assets/docs/TOPICS.md"><img src="https://img.shields.io/badge/-题库目录-blue" alt="题库目录"></a>
88
<a href="./assets/docs/CATEGORIES.md"><img src="https://img.shields.io/badge/-题库分类-red" alt="题库分类"></a>

assets/data/categories.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,12 @@
682682
"path": "./problemset/count-of-range-sum/README.md",
683683
"difficulty": "困难"
684684
},
685+
{
686+
"id": "937",
687+
"title": "重新排列日志文件",
688+
"path": "./problemset/reorder-data-in-log-files/README.md",
689+
"difficulty": "简单"
690+
},
685691
{
686692
"id": "954",
687693
"title": "二倍数对数组",

assets/data/topics.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3149,6 +3149,16 @@
31493149
"url": "https://leetcode-cn.com/problems/reverse-only-letters/",
31503150
"path": "./problemset/reverse-only-letters/README.md"
31513151
},
3152+
{
3153+
"id": "937",
3154+
"title": {
3155+
"cn": "重新排列日志文件",
3156+
"en": "reorder-data-in-log-files"
3157+
},
3158+
"difficulty": "简单",
3159+
"url": "https://leetcode-cn.com/problems/reorder-data-in-log-files/",
3160+
"path": "./problemset/reorder-data-in-log-files/README.md"
3161+
},
31523162
{
31533163
"id": "954",
31543164
"title": {

assets/docs/CATEGORIES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
| 315. [计算右侧小于当前元素的个数](../../problemset/count-of-smaller-numbers-after-self/README.md) | 困难 |
135135
| 324. [摆动排序 II](../../problemset/wiggle-sort-2/README.md) | 中等 |
136136
| 327. [区间和的个数](../../problemset/count-of-range-sum/README.md) | 困难 |
137+
| 937. [重新排列日志文件](../../problemset/reorder-data-in-log-files/README.md) | 简单 |
137138
| 954. [二倍数对数组](../../problemset/array-of-doubled-pairs/README.md) | 中等 |
138139
| 1984. [学生分数的最小差值](../../problemset/minimum-difference-between-highest-and-lowest-of-k-scores/README.md) | 简单 |
139140
| 1996. [游戏中弱角色的数量](../../problemset/the-number-of-weak-characters-in-the-game/README.md) | 中等 |

assets/docs/TOPICS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@
630630

631631
[917. 仅仅反转字母](../../problemset/reverse-only-letters/README.md)
632632

633+
[937. 重新排列日志文件](../../problemset/reorder-data-in-log-files/README.md)
634+
633635
[954. 二倍数对数组](../../problemset/array-of-doubled-pairs/README.md)
634636

635637
[969. 煎饼排序](../../problemset/pancake-sorting/README.md)
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# 重新排列日志文件
2+
3+
> 难度:简单
4+
>
5+
> https://leetcode-cn.com/problems/reorder-data-in-log-files/
6+
7+
## 题目
8+
9+
给你一个日志数组 `logs`。每条日志都是以空格分隔的字串,其第一个字为字母与数字混合的 **标识符**
10+
11+
有两种不同类型的日志:
12+
13+
- **字母日志**:除标识符之外,所有字均由小写字母组成
14+
- **数字日志**:除标识符之外,所有字均由数字组成
15+
16+
请按下述规则将日志重新排序:
17+
18+
- 所有 **字母日志** 都排在 **数字日志** 之前。
19+
- **字母日志** 在内容不同时,忽略标识符后,按内容字母顺序排序;在内容相同时,按标识符排序。
20+
- **数字日志** 应该保留原来的相对顺序。
21+
22+
返回日志的最终顺序。
23+
24+
### 示例
25+
26+
#### 示例 1:
27+
28+
```
29+
输入:logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"]
30+
输出:["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"]
31+
解释:
32+
字母日志的内容都不同,所以顺序为 "art can", "art zero", "own kit dig" 。
33+
数字日志保留原来的相对顺序 "dig1 8 1 5 1", "dig2 3 6" 。
34+
```
35+
36+
#### 示例 2:
37+
38+
```
39+
输入:logs = ["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo"]
40+
输出:["g1 act car","a8 act zoo","ab1 off key dog","a1 9 2 3 1","zo4 4 7"]
41+
```
42+
43+
## 解题
44+
45+
```ts
46+
/**
47+
* 自定义排序
48+
* @desc 时间复杂度 O(NlogN) 空间复杂度 O(N)
49+
* @param logs
50+
* @returns
51+
*/
52+
export function reorderLogFiles(logs: string[]): string[] {
53+
return logs
54+
.map<[string, number]>((log, i) => [log, i])
55+
.sort((a, b) => logCompare(a, b))
56+
.map(item => item[0])
57+
58+
function logCompare(a: [string, number], b: [string, number]): number {
59+
const log1 = split(a[0])
60+
const log2 = split(b[0])
61+
const isDigit1 = !isNaN(Number(log1[1][0]))
62+
const isDigit2 = !isNaN(Number(log2[1][0]))
63+
if (isDigit1 && isDigit2)
64+
return a[1] - b[1]
65+
66+
if (!isDigit1 && !isDigit2) {
67+
const sc = compareTo(log1[1], log2[1])
68+
69+
if (sc !== 0) return sc
70+
return compareTo(log1[0], log2[0])
71+
}
72+
73+
return isDigit1 ? 1 : -1
74+
}
75+
76+
function split(str: string, separator = ' '): string[] {
77+
const arr = str.split(separator)
78+
return [arr.shift()!, arr.join(separator)]
79+
}
80+
81+
function compareTo(left: string, right: string): -1 | 0 | 1 {
82+
let diff: number
83+
for (let i = 0; i < Math.min(left.length, right.length); i++) {
84+
diff = left[i].charCodeAt(0) - right[i].charCodeAt(0)
85+
if (diff !== 0)
86+
return diff < 0 ? -1 : 1
87+
}
88+
89+
diff = left.length - right.length
90+
return diff === 0
91+
? 0
92+
: diff < 0
93+
? -1
94+
: 1
95+
}
96+
}
97+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { reorderLogFiles } from '.'
3+
4+
describe('重新排列日志文件', () => {
5+
testCase(reorderLogFiles)
6+
})
7+
8+
function testCase(fn: (logs: string[]) => string[]) {
9+
it.each([
10+
[
11+
['dig1 8 1 5 1', 'let1 art can', 'dig2 3 6', 'let2 own kit dig', 'let3 art zero'],
12+
['let1 art can', 'let3 art zero', 'let2 own kit dig', 'dig1 8 1 5 1', 'dig2 3 6'],
13+
],
14+
[
15+
['a1 9 2 3 1', 'g1 act car', 'zo4 4 7', 'ab1 off key dog', 'a8 act zoo'],
16+
['g1 act car', 'a8 act zoo', 'ab1 off key dog', 'a1 9 2 3 1', 'zo4 4 7'],
17+
],
18+
[
19+
['1 n u', 'r 527', 'j 893', '6 14', '6 82'],
20+
['1 n u', 'r 527', 'j 893', '6 14', '6 82'],
21+
],
22+
])('示例%#', (logs, expected) => {
23+
expect(fn(logs)).toStrictEqual(expected)
24+
})
25+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* 自定义排序
3+
* @desc 时间复杂度 O(NlogN) 空间复杂度 O(N)
4+
* @param logs
5+
* @returns
6+
*/
7+
export function reorderLogFiles(logs: string[]): string[] {
8+
return logs
9+
.map<[string, number]>((log, i) => [log, i])
10+
.sort((a, b) => logCompare(a, b))
11+
.map(item => item[0])
12+
13+
function logCompare(a: [string, number], b: [string, number]): number {
14+
const log1 = split(a[0])
15+
const log2 = split(b[0])
16+
const isDigit1 = !isNaN(Number(log1[1][0]))
17+
const isDigit2 = !isNaN(Number(log2[1][0]))
18+
if (isDigit1 && isDigit2)
19+
return a[1] - b[1]
20+
21+
if (!isDigit1 && !isDigit2) {
22+
const sc = compareTo(log1[1], log2[1])
23+
24+
if (sc !== 0) return sc
25+
return compareTo(log1[0], log2[0])
26+
}
27+
28+
return isDigit1 ? 1 : -1
29+
}
30+
31+
function split(str: string, separator = ' '): string[] {
32+
const arr = str.split(separator)
33+
return [arr.shift()!, arr.join(separator)]
34+
}
35+
36+
function compareTo(left: string, right: string): -1 | 0 | 1 {
37+
let diff: number
38+
for (let i = 0; i < Math.min(left.length, right.length); i++) {
39+
diff = left[i].charCodeAt(0) - right[i].charCodeAt(0)
40+
if (diff !== 0)
41+
return diff < 0 ? -1 : 1
42+
}
43+
44+
diff = left.length - right.length
45+
return diff === 0
46+
? 0
47+
: diff < 0
48+
? -1
49+
: 1
50+
}
51+
}

0 commit comments

Comments
 (0)