Skip to content

Commit 5dc857e

Browse files
committed
[新增] 新增题目:125、273、706
1 parent 5843000 commit 5dc857e

9 files changed

+341
-0
lines changed

src/125_validPalindrome.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
125. 验证回文串
3+
https://leetcode.cn/problems/valid-palindrome/
4+
难度:简单
5+
6+
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
7+
字母和数字都属于字母数字字符。
8+
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
9+
10+
示例 1:
11+
输入: s = "A man, a plan, a canal: Panama"
12+
输出:true
13+
解释:"amanaplanacanalpanama" 是回文串。
14+
15+
示例 2:
16+
输入:s = "race a car"
17+
输出:false
18+
解释:"raceacar" 不是回文串。
19+
20+
示例 3:
21+
输入:s = " "
22+
输出:true
23+
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。由于空字符串正着反着读都一样,所以是回文串。
24+
*/
25+
26+
/**
27+
* 判断是否为会文本
28+
* @param {string} s - 待判断的字符串
29+
* @returns {boolean} 是否为回文本
30+
*/
31+
export function isPalindrome (s: string): boolean {
32+
s = s.toLowerCase()
33+
s = s.match(/([a-z]|[A-Z]|\d)/g)?.join('') ?? ''
34+
for (let i = 0; i <= Math.floor(s.length / 2); i++) {
35+
if (s[i] !== s[s.length - (i + 1)]) return false
36+
}
37+
return true
38+
}

src/273_integerToEnglishWords.ts

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
273. 整数转换英文表示
3+
https://leetcode.cn/problems/integer-to-english-words/
4+
难度:困难
5+
6+
将非负整数 num 转换为其对应的英文表示。
7+
8+
示例 1:
9+
输入:num = 123
10+
输出:"One Hundred Twenty Three"
11+
12+
示例 2:
13+
输入:num = 12345
14+
输出:"Twelve Thousand Three Hundred Forty Five"
15+
16+
示例 3:
17+
输入:num = 1234567
18+
输出:"One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
19+
20+
提示:0 <= num <= 2^31 - 1
21+
*/
22+
23+
/** 特殊数字字典(0 ~ 19) */
24+
const DIGIT_MAP_0_19: Record<string | number, string> = {
25+
0: 'Zero',
26+
1: 'One',
27+
2: 'Two',
28+
3: 'Three',
29+
4: 'Four',
30+
5: 'Five',
31+
6: 'Six',
32+
7: 'Seven',
33+
8: 'Eight',
34+
9: 'Nine',
35+
10: 'Ten',
36+
11: 'Eleven',
37+
12: 'Twelve',
38+
13: 'Thirteen',
39+
14: 'Fourteen',
40+
15: 'Fifteen',
41+
16: 'Sixteen',
42+
17: 'Seventeen',
43+
18: 'Eighteen',
44+
19: 'Nineteen'
45+
}
46+
/** 十位字典(20 ~ 90) */
47+
const DIGIT_DECIMAL_MAP: Record<string | number, string> = {
48+
2: 'Twenty',
49+
3: 'Thirty',
50+
4: 'Forty',
51+
5: 'Fifty',
52+
6: 'Sixty',
53+
7: 'Seventy',
54+
8: 'Eighty',
55+
9: 'Ninety'
56+
}
57+
58+
/**
59+
* 解析十位与个位的英文(0 ~ 99)
60+
* @param {string} numStr - 数字字符串
61+
* @returns {string} 0 ~ 99 所对应的英文
62+
*/
63+
function parseDecimal (numStr: string): string {
64+
// 保留个位和十位
65+
numStr = numStr.substring(numStr.length - 2)
66+
// 小于或等于 19 直接使用特殊数字字典解析
67+
const num = Number.parseInt(numStr)
68+
if (num <= 19) return DIGIT_MAP_0_19[num] ?? ''
69+
// 大于 19 分别解析个位和十位
70+
let result: string = ''
71+
// 解析十位
72+
result = DIGIT_DECIMAL_MAP[numStr[numStr.length - 2]]
73+
// 解析个位(个位不为 0)
74+
if (numStr[numStr.length - 1] !== '0') {
75+
result = `${result} ${DIGIT_MAP_0_19[numStr[numStr.length - 1]]}`
76+
}
77+
return result ?? ''
78+
}
79+
80+
/**
81+
* 解析百位及以下的英文(0 ~ 999)
82+
* @param numStr - 数字字符串
83+
* @returns {string} 0 ~ 999 所对应的英文
84+
*/
85+
function parseHundred (numStr: string): string {
86+
if (numStr.length < 3) return parseDecimal(numStr)
87+
// 保留最后的数字到百位
88+
numStr = numStr.substring(numStr.length - 3)
89+
// 解析百位的英文
90+
let result: string = ''
91+
if (numStr[0] !== '0') result = `${DIGIT_MAP_0_19[numStr[0]]} Hundred`
92+
// 个位和十位不为 0 时解析个位与十位的英文
93+
const decimalStr = numStr.substring(1)
94+
if (decimalStr !== '00') result = (result !== '' ? `${result} ` : '') + parseDecimal(decimalStr)
95+
return result
96+
}
97+
98+
/**
99+
* 数字转英文
100+
* + LeetCode 入口
101+
* @param {number} num - 0 ~ 2^31 - 1 之间的整数
102+
* @returns {string} 数字所对应的英文
103+
*/
104+
function numberToWords (num: number): string {
105+
const numStr: string = num.toString(10)
106+
let result: string = ''
107+
// 解析 Hundred 及以下
108+
result = parseHundred(numStr)
109+
if (numStr.length <= 3) return result
110+
111+
// 解析 Thousand
112+
const thousandStr = numStr.substring(numStr.length - 6, numStr.length - 3)
113+
if (thousandStr !== '000') result = `${parseHundred(thousandStr)} Thousand` + (result !== '' ? ` ${result}` : '')
114+
if (numStr.length <= 6) return result
115+
116+
// 解析 Million
117+
const millionStr = numStr.substring(numStr.length - 9, numStr.length - 6)
118+
if (millionStr !== '000') result = `${parseHundred(millionStr)} Million` + (result !== '' ? ` ${result}` : '')
119+
if (numStr.length <= 9) return result
120+
121+
// 解析 Billion
122+
const billionStr = numStr.substring(numStr.length - 11, numStr.length - 9)
123+
if (billionStr !== '000') result = `${parseHundred(billionStr)} Billion` + (result !== '' ? ` ${result}` : '')
124+
return result
125+
}
126+
127+
export { numberToWords }

src/706_designHashMap.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
706. 设计哈希映射
3+
https://leetcode.cn/problems/design-hashmap/
4+
难度:简单
5+
6+
不使用任何内建的哈希表库设计一个哈希映射(HashMap),实现 MyHashMap 类。
7+
8+
MyHashMap() 用空映射初始化对象
9+
void put(int key, int value) 向 HashMap 插入一个键值对 (key, value) 。如果 key 已经存在于映射中,则更新其对应的值 value 。
10+
int get(int key) 返回特定的 key 所映射的 value ;如果映射中不包含 key 的映射,返回 -1 。
11+
void remove(key) 如果映射中存在 key 的映射,则移除 key 和它所对应的 value 。
12+
13+
示例:
14+
15+
输入:
16+
["MyHashMap", "put", "put", "get", "get", "put", "get", "remove", "get"]
17+
[[], [1, 1], [2, 2], [1], [3], [2, 1], [2], [2], [2]]
18+
输出:
19+
[null, null, null, 1, -1, null, 1, null, -1]
20+
21+
解释:
22+
MyHashMap myHashMap = new MyHashMap();
23+
myHashMap.put(1, 1); // myHashMap 现在为 [[1,1]]
24+
myHashMap.put(2, 2); // myHashMap 现在为 [[1,1], [2,2]]
25+
myHashMap.get(1); // 返回 1 ,myHashMap 现在为 [[1,1], [2,2]]
26+
myHashMap.get(3); // 返回 -1(未找到),myHashMap 现在为 [[1,1], [2,2]]
27+
myHashMap.put(2, 1); // myHashMap 现在为 [[1,1], [2,1]](更新已有的值)
28+
myHashMap.get(2); // 返回 1 ,myHashMap 现在为 [[1,1], [2,1]]
29+
myHashMap.remove(2); // 删除键为 2 的数据,myHashMap 现在为 [[1,1]]
30+
myHashMap.get(2); // 返回 -1(未找到),myHashMap 现在为 [[1,1]]
31+
32+
提示:
33+
34+
0 <= key, value <= 106
35+
最多调用 104 次 put、get 和 remove 方法
36+
*/
37+
38+
import testCases from '../tests/testCases/706_designHashMap'
39+
40+
class MyHashMap {
41+
mapLikedArray: number[][] = []
42+
43+
constructor (mapLikedArray?: number[][]) {
44+
if (mapLikedArray != null) this.mapLikedArray = mapLikedArray
45+
}
46+
47+
put (key: number, value: number): void {
48+
const index = this.mapLikedArray.findIndex(item => item[0] === key)
49+
if (index === -1) {
50+
this.mapLikedArray.push([key, value])
51+
return
52+
}
53+
this.mapLikedArray[index][1] = value
54+
}
55+
56+
get (key: number): number {
57+
const value = this.mapLikedArray.find(item => item[0] === key)
58+
return value === undefined ? -1 : value[1]
59+
}
60+
61+
remove (key: number): void {
62+
const index = this.mapLikedArray.findIndex(item => item[0] === key)
63+
if (index > -1) this.mapLikedArray.splice(index, 1)
64+
}
65+
}
66+
67+
export function main (
68+
operations: string[],
69+
params: number[][]
70+
): Array<number | null> {
71+
const operationRecords: Array<number | null> = [null]
72+
const myHashMap = new MyHashMap()
73+
74+
operations.forEach((operation, index) => {
75+
switch (operation) {
76+
case 'put': {
77+
myHashMap.put(params[index][0], params[index][1])
78+
operationRecords.push(null)
79+
break
80+
}
81+
case 'get': {
82+
operationRecords.push(myHashMap.get(params[index][0]))
83+
break
84+
}
85+
case 'remove': {
86+
myHashMap.remove(params[index][0])
87+
operationRecords.push(null)
88+
break
89+
}
90+
}
91+
})
92+
93+
return operationRecords
94+
}
95+
96+
// Debug
97+
if (require.main === module) {
98+
main(testCases[0].input.operations, testCases[0].input.params)
99+
}

tests/125_validPalindrome.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { describe, expect, test } from '@jest/globals'
2+
import testCases from './testCases/125_validPalindrome'
3+
import { isPalindrome } from '../src/125_validPalindrome'
4+
5+
describe('125. Valid palindrome', () => {
6+
testCases.forEach(testCase => {
7+
test(`Input: "${testCase.input}"`, () => {
8+
expect(isPalindrome(testCase.input)).toBe(testCase.expected)
9+
})
10+
})
11+
})
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { describe, test, expect } from '@jest/globals'
2+
import testCases from './testCases/273_integerToEnglishWords'
3+
import { numberToWords } from '../src/273_integerToEnglishWords'
4+
5+
describe('273. Integer to english words', () => {
6+
testCases.forEach((testCase, index) => {
7+
test(`Test case index: ${index}, Input: ${testCase.input}`, () => {
8+
expect(numberToWords(testCase.input)).toBe(testCase.expected)
9+
})
10+
})
11+
})

tests/706_designHashMap.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { describe, test, expect } from '@jest/globals'
2+
import testCases from './testCases/706_designHashMap'
3+
import { main } from '../src/706_designHashMap'
4+
5+
describe('706. Design Hash Map', () => {
6+
testCases.forEach((testCase, index) => {
7+
test(`Test case index: ${index}`, () => {
8+
expect(main(testCase.input.operations, testCase.input.params)).toEqual(testCase.expected)
9+
})
10+
})
11+
})
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default [
2+
{ input: 'A man, a plan, a canal: Panama', expected: true },
3+
{ input: 'race a car', expected: false },
4+
{ input: ' ', expected: true },
5+
{ input: '.', expected: true },
6+
{ input: '.,', expected: true },
7+
{ input: '0P', expected: false }
8+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export default [
2+
{ input: 0, expected: 'Zero' },
3+
{ input: 1, expected: 'One' },
4+
{ input: 20, expected: 'Twenty' },
5+
{ input: 100, expected: 'One Hundred' },
6+
{ input: 1000, expected: 'One Thousand' },
7+
{ input: 10000, expected: 'Ten Thousand' },
8+
{ input: 100000, expected: 'One Hundred Thousand' },
9+
{ input: 101, expected: 'One Hundred One' },
10+
{ input: 1001, expected: 'One Thousand One' },
11+
{ input: 10001, expected: 'Ten Thousand One' },
12+
{ input: 1000000, expected: 'One Million' },
13+
{ input: 12, expected: 'Twelve' },
14+
{ input: 13, expected: 'Thirteen' },
15+
{ input: 73, expected: 'Seventy Three' },
16+
{ input: 123, expected: 'One Hundred Twenty Three' },
17+
{ input: 12345, expected: 'Twelve Thousand Three Hundred Forty Five' },
18+
{ input: 1234567, expected: 'One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven' },
19+
{ input: 1234567891, expected: 'One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One' }
20+
]

tests/testCases/706_designHashMap.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export default [
2+
{
3+
input: {
4+
operations: ['MyHashMap', 'put', 'put', 'get', 'get', 'put', 'get', 'remove', 'get'],
5+
params: [[], [1, 1], [2, 2], [1], [3], [2, 1], [2], [2], [2]]
6+
},
7+
expected: [null, null, null, 1, -1, null, 1, null, -1]
8+
},
9+
{
10+
input: {
11+
operations: ['MyHashMap', 'remove', 'put', 'remove', 'remove', 'get', 'remove', 'put', 'get', 'remove', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'remove', 'put', 'put', 'get', 'put', 'get', 'put', 'put', 'get', 'put', 'remove', 'remove', 'put', 'put', 'get', 'remove', 'put', 'put', 'put', 'get', 'put', 'put', 'remove', 'put', 'remove', 'remove', 'remove', 'put', 'remove', 'get', 'put', 'put', 'put', 'put', 'remove', 'put', 'get', 'put', 'put', 'get', 'put', 'remove', 'get', 'get', 'remove', 'put', 'put', 'put', 'put', 'put', 'put', 'get', 'get', 'remove', 'put', 'put', 'put', 'put', 'get', 'remove', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'put', 'remove', 'remove', 'get', 'remove', 'put', 'put', 'remove', 'get', 'put', 'put'],
12+
params: [[], [27], [65, 65], [19], [0], [18], [3], [42, 0], [19], [42], [17, 90], [31, 76], [48, 71], [5, 50], [7, 68], [73, 74], [85, 18], [74, 95], [84, 82], [59, 29], [71, 71], [42], [51, 40], [33, 76], [17], [89, 95], [95], [30, 31], [37, 99], [51], [95, 35], [65], [81], [61, 46], [50, 33], [59], [5], [75, 89], [80, 17], [35, 94], [80], [19, 68], [13, 17], [70], [28, 35], [99], [37], [13], [90, 83], [41], [50], [29, 98], [54, 72], [6, 8], [51, 88], [13], [8, 22], [85], [31, 22], [60, 9], [96], [6, 35], [54], [15], [28], [51], [80, 69], [58, 92], [13, 12], [91, 56], [83, 52], [8, 48], [62], [54], [25], [36, 4], [67, 68], [83, 36], [47, 58], [82], [36], [30, 85], [33, 87], [42, 18], [68, 83], [50, 53], [32, 78], [48, 90], [97, 95], [13, 8], [15, 7], [5], [42], [20], [65], [57, 9], [2, 41], [6], [33], [16, 44], [95, 30]]
13+
},
14+
expected: [null, null, null, null, null, -1, null, null, -1, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 90, null, -1, null, null, 40, null, null, null, null, null, 29, null, null, null, null, 17, null, null, null, null, null, null, null, null, null, 33, null, null, null, null, null, null, 18, null, null, -1, null, null, -1, 35, null, null, null, null, null, null, null, -1, -1, null, null, null, null, null, -1, null, null, null, null, null, null, null, null, null, null, null, null, null, -1, null, null, null, null, 87, null, null]
15+
}
16+
]

0 commit comments

Comments
 (0)