Skip to content

Commit 058895e

Browse files
committed
feat: ^_^
1 parent e37dce1 commit 058895e

9 files changed

+365
-1
lines changed

10.正则表达式匹配.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* @lc app=leetcode.cn id=10 lang=typescript
3+
*
4+
* [10] 正则表达式匹配
5+
*
6+
* https://leetcode-cn.com/problems/regular-expression-matching/description/
7+
*
8+
* algorithms
9+
* Hard (31.65%)
10+
* Likes: 2750
11+
* Dislikes: 0
12+
* Total Accepted: 242.8K
13+
* Total Submissions: 767.8K
14+
* Testcase Example: '"aa"\n"a"'
15+
*
16+
* 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
17+
*
18+
*
19+
* '.' 匹配任意单个字符
20+
* '*' 匹配零个或多个前面的那一个元素
21+
*
22+
*
23+
* 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
24+
*
25+
*
26+
* 示例 1:
27+
*
28+
*
29+
* 输入:s = "aa", p = "a"
30+
* 输出:false
31+
* 解释:"a" 无法匹配 "aa" 整个字符串。
32+
*
33+
*
34+
* 示例 2:
35+
*
36+
*
37+
* 输入:s = "aa", p = "a*"
38+
* 输出:true
39+
* 解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
40+
*
41+
*
42+
* 示例 3:
43+
*
44+
*
45+
* 输入:s = "ab", p = ".*"
46+
* 输出:true
47+
* 解释:".*" 表示可匹配零个或多个('*')任意字符('.')。
48+
*
49+
*
50+
*
51+
*
52+
* 提示:
53+
*
54+
*
55+
* 1 <= s.length <= 20
56+
* 1 <= p.length <= 30
57+
* s 只包含从 a-z 的小写字母。
58+
* p 只包含从 a-z 的小写字母,以及字符 . 和 *。
59+
* 保证每次出现字符 * 时,前面都匹配到有效的字符
60+
*
61+
*
62+
*/
63+
64+
export
65+
// @lc code=start
66+
function isMatch(s: string, p: string): boolean {
67+
const dp = new Array(s.length + 1)
68+
.fill(0)
69+
.map(() => new Array(p.length + 1).fill(false))
70+
dp[0][0] = true
71+
72+
for (let i = 0; i <= s.length; i++) {
73+
const charS = s[i - 1]
74+
75+
for (let j = 1; j <= p.length; j++) {
76+
const charP = p[j - 1]
77+
78+
if (i === 0) {
79+
dp[i][j] = charP === '*' && dp[i][j - 2]
80+
} else if (charP === '.') {
81+
dp[i][j] = dp[i - 1][j - 1]
82+
} else if (charP === '*' && p[j - 2] !== '.') {
83+
dp[i][j] = dp[i][j - 2] || (dp[i - 1][j] && charS === p[j - 2])
84+
} else if (charP === '*' && p[j - 2] === '.') {
85+
dp[i][j] = dp[i][j - 2] || dp[i - 1][j]
86+
} else {
87+
dp[i][j] = dp[i - 1][j - 1] && charS === charP
88+
}
89+
}
90+
}
91+
92+
return dp[s.length][p.length]
93+
}
94+
// @lc code=end

23.合并k个升序链表.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* @lc app=leetcode.cn id=23 lang=typescript
3+
*
4+
* [23] 合并K个升序链表
5+
*
6+
* https://leetcode-cn.com/problems/merge-k-sorted-lists/description/
7+
*
8+
* algorithms
9+
* Hard (56.45%)
10+
* Likes: 1757
11+
* Dislikes: 0
12+
* Total Accepted: 394.6K
13+
* Total Submissions: 698.7K
14+
* Testcase Example: '[[1,4,5],[1,3,4],[2,6]]'
15+
*
16+
* 给你一个链表数组,每个链表都已经按升序排列。
17+
*
18+
* 请你将所有链表合并到一个升序链表中,返回合并后的链表。
19+
*
20+
*
21+
*
22+
* 示例 1:
23+
*
24+
* 输入:lists = [[1,4,5],[1,3,4],[2,6]]
25+
* 输出:[1,1,2,3,4,4,5,6]
26+
* 解释:链表数组如下:
27+
* [
28+
* ⁠ 1->4->5,
29+
* ⁠ 1->3->4,
30+
* ⁠ 2->6
31+
* ]
32+
* 将它们合并到一个有序链表中得到。
33+
* 1->1->2->3->4->4->5->6
34+
*
35+
*
36+
* 示例 2:
37+
*
38+
* 输入:lists = []
39+
* 输出:[]
40+
*
41+
*
42+
* 示例 3:
43+
*
44+
* 输入:lists = [[]]
45+
* 输出:[]
46+
*
47+
*
48+
*
49+
*
50+
* 提示:
51+
*
52+
*
53+
* k == lists.length
54+
* 0 <= k <= 10^4
55+
* 0 <= lists[i].length <= 500
56+
* -10^4 <= lists[i][j] <= 10^4
57+
* lists[i] 按 升序 排列
58+
* lists[i].length 的总和不超过 10^4
59+
*
60+
*
61+
*/
62+
63+
import { PriorityQueue } from '@datastructures-js/priority-queue'
64+
import { ListNode } from './commons/list'
65+
66+
export
67+
// @lc code=start
68+
function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
69+
const priorityQueue = new PriorityQueue<ListNode<number>>({
70+
compare: (a, b) => a.val - b.val,
71+
})
72+
for (const n of lists) {
73+
if (n) {
74+
priorityQueue.enqueue(n)
75+
}
76+
}
77+
78+
const dummyHead = new ListNode(-1)
79+
let prev = dummyHead
80+
while (!priorityQueue.isEmpty()) {
81+
const node = priorityQueue.dequeue() as ListNode<number>
82+
prev.next = node
83+
prev = node
84+
85+
if (node.next) {
86+
priorityQueue.enqueue(node.next)
87+
}
88+
}
89+
90+
return dummyHead.next
91+
}
92+
93+
// FIXME: 不能提交!!!LeetCode 没得 PriorityQueue!!
94+
// @lc code=end
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* @lc app=leetcode.cn id=285 lang=typescript
3+
*
4+
* [285] 二叉搜索树中的中序后继
5+
*
6+
* https://leetcode-cn.com/problems/inorder-successor-in-bst/description/
7+
*
8+
* algorithms
9+
* Medium (63.82%)
10+
* Likes: 149
11+
* Dislikes: 0
12+
* Total Accepted: 10K
13+
* Total Submissions: 15.6K
14+
* Testcase Example: '[2,1,3]\n1'
15+
*
16+
* 给定一棵二叉搜索树和其中的一个节点 p ,找到该节点在树中的中序后继。如果节点没有中序后继,请返回 null 。
17+
*
18+
* 节点 p 的后继是值比 p.val 大的节点中键值最小的节点。
19+
*
20+
*
21+
*
22+
* 示例 1:
23+
*
24+
*
25+
*
26+
*
27+
* 输入:root = [2,1,3], p = 1
28+
* 输出:2
29+
* 解释:这里 1 的中序后继是 2。请注意 p 和返回值都应是 TreeNode 类型。
30+
*
31+
*
32+
* 示例 2:
33+
*
34+
*
35+
*
36+
*
37+
* 输入:root = [5,3,6,2,4,null,null,1], p = 6
38+
* 输出:null
39+
* 解释:因为给出的节点没有中序后继,所以答案就返回 null 了。
40+
*
41+
*
42+
*
43+
*
44+
* 提示:
45+
*
46+
*
47+
* 树中节点的数目在范围 [1, 10^4] 内。
48+
* -10^5
49+
* 树中各节点的值均保证唯一。
50+
*
51+
*
52+
*/
53+
54+
import { TreeNode } from './commons/Tree'
55+
56+
export
57+
// @lc code=start
58+
function inorderSuccessor(root: TreeNode, p: TreeNode): TreeNode | null {
59+
if (p.right) {
60+
return findLeftMost(p.right)
61+
}
62+
63+
let curr = root
64+
const path = []
65+
66+
while (curr !== p) {
67+
path.push(curr)
68+
69+
if (curr.val > p.val) {
70+
curr = curr.left!
71+
} else {
72+
curr = curr.right!
73+
}
74+
}
75+
76+
let end = p
77+
while (path.length && path[path.length - 1].right === end) {
78+
end = path.pop()!
79+
}
80+
81+
if (path.length && path[path.length - 1].left === end) {
82+
return path[path.length - 1]
83+
}
84+
85+
return null
86+
}
87+
88+
function findLeftMost(node: TreeNode | null) {
89+
let curr = node
90+
while (curr && curr.left) {
91+
curr = curr.left
92+
}
93+
return curr
94+
}
95+
// @lc code=end

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"license": "MIT",
88
"private": true,
99
"dependencies": {
10+
"@datastructures-js/priority-queue": "^5.3.0",
1011
"@types/jest": "^27.4.0",
1112
"jest": "^27.5.0",
1213
"ts-jest": "^27.1.3",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { isMatch } from '../10.正则表达式匹配'
2+
3+
describe('10.正则表达式匹配', () => {
4+
it('should work', () => {
5+
expect(isMatch('aa', 'a'))
6+
.toBe(false)
7+
expect(isMatch('aa', 'a*'))
8+
.toBe(true)
9+
expect(isMatch('ab', '.*'))
10+
.toBe(true)
11+
expect(isMatch('aaaaabaaaa', 'a*'))
12+
.toBe(false)
13+
expect(isMatch('aavaaaaaaaa', 'a..a*'))
14+
.toBe(true)
15+
expect(isMatch('', 'a*.*a*b*'))
16+
.toBe(true)
17+
expect(isMatch('ab', '.*'))
18+
.toBe(true)
19+
})
20+
})
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { mergeKLists } from '../23.合并k个升序链表'
2+
import { ListNode } from '../commons/list'
3+
4+
describe('23.合并k个升序链表', () => {
5+
it('should work', () => {
6+
let nodes: Array<ListNode | null>
7+
8+
nodes = [[1, 4, 5], [1, 3, 4], [2, 6]].map((x) => ListNode.fromArray(x))
9+
mergeKLists(nodes)
10+
expect(nodes[0]?.toString())
11+
.toBe(ListNode.fromArray([1, 1, 2, 3, 4, 4, 5, 6])!.toString())
12+
13+
nodes = []
14+
expect(() => mergeKLists(nodes)).not.toThrow()
15+
16+
nodes = [null]
17+
expect(() => mergeKLists(nodes)).not.toThrow()
18+
})
19+
})
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { inorderSuccessor } from '../285.二叉搜索树中的中序后继'
2+
import { TreeNode } from '../commons/Tree'
3+
4+
describe('285.二叉搜索树中的中序后继', () => {
5+
it('should work', () => {
6+
let root: TreeNode
7+
let node: TreeNode
8+
let result: TreeNode
9+
10+
root = TreeNode.fromArray([41, 37, 44, 24, 39, 42, 48, 1, 35, 38, 40, null, 43, 46, 49, 0, 2, 30, 36, null, null, null, null, null, null, 45, 47, null, null, null, null, null, 4, 29, 32, null, null, null, null, null, null, 3, 9, 26, null, 31, 34, null, null, 7, 11, 25, 27, null, null, 33, null, 6, 8, 10, 16, null, null, null, 28, null, null, 5, null, null, null, null, null, 15, 19, null, null, null, null, 12, null, 18, 20, null, 13, 17, null, null, 22, null, 14, null, null, 21, 23])!
11+
node = root.left!.right!.right!
12+
result = root
13+
expect(inorderSuccessor(root, node)).toBe(result)
14+
15+
root = TreeNode.fromArray([8, 5, 9, 3, 7])!
16+
node = root.left!.right!
17+
result = root
18+
expect(inorderSuccessor(root, node)).toBe(result)
19+
20+
root = TreeNode.fromArray([2, 1, 3])!
21+
node = root.left!
22+
result = root
23+
expect(inorderSuccessor(root, node)).toBe(result)
24+
25+
root = TreeNode.fromArray([5, 3, 6, 2, 4, null, null, 1])!
26+
node = root.right!
27+
expect(inorderSuccessor(root, node)).toBeNull()
28+
})
29+
})

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
55
"module": "commonjs",
66
/* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
7-
// "allowJs": true, /* Allow javascript files to be compiled. */
7+
"allowJs": true, /* Allow javascript files to be compiled. */
88
// "checkJs": true, /* Report errors in .js files. */
99
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
1010
// "declaration": true, /* Generates corresponding '.d.ts' file. */

yarn.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,18 @@
305305
dependencies:
306306
"@cspotcode/source-map-consumer" "0.8.0"
307307

308+
"@datastructures-js/heap@^3.2.0":
309+
version "3.2.0"
310+
resolved "https://registry.npmmirror.com/@datastructures-js/heap/-/heap-3.2.0.tgz#d8fcdbf58c462c8a3f0fdfd9c6a57ca11505321e"
311+
integrity sha512-FcU5ZAyb+VIOZz1HABsJUsbJi2ZyUDO7aoe97hq4d3tK3z8nMgwdxf5bO0gafR0ExFi18YTspntqHLzt4XOgnA==
312+
313+
"@datastructures-js/priority-queue@^5.3.0":
314+
version "5.3.0"
315+
resolved "https://registry.npmmirror.com/@datastructures-js/priority-queue/-/priority-queue-5.3.0.tgz#89afce79a19a3226c12cc6e9288f94ff60af26cf"
316+
integrity sha512-0Dl0UooE9Uzz85qBP46HTjQHS5GN7NMNluN5/nMfxQAndG/1eNBJpBntLGT5QJarvMO3poLNBJzA3S4GPajp+w==
317+
dependencies:
318+
"@datastructures-js/heap" "^3.2.0"
319+
308320
"@eslint/eslintrc@^1.1.0":
309321
version "1.1.0"
310322
resolved "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-1.1.0.tgz#583d12dbec5d4f22f333f9669f7d0b7c7815b4d3"

0 commit comments

Comments
 (0)