Skip to content

Commit 84b6580

Browse files
committed
feat: update 6 leetcode
1 parent dbcb5d0 commit 84b6580

6 files changed

+353
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* @lc app=leetcode id=1446 lang=typescript
3+
*
4+
* [1446] Consecutive Characters
5+
*/
6+
7+
// @lc code=start
8+
/**
9+
* @description: 类似动态规划的思路?
10+
* 时间复杂度 O(n)
11+
* 空间复杂度 O(1)
12+
* @param {string} s
13+
* @return {number}
14+
*/
15+
function maxPower(s: string): number {
16+
if (s.length <= 1) return 1;
17+
let maxLength = 1;
18+
let curLength = 1;
19+
20+
for (let i = 1; i < s.length; i++) {
21+
if (s[i] !== s[i - 1]) {
22+
curLength = 1;
23+
continue;
24+
}
25+
curLength += 1;
26+
27+
if (curLength > maxLength) {
28+
maxLength = curLength;
29+
}
30+
}
31+
32+
return maxLength;
33+
}
34+
/**
35+
* @description: 使用哈希表的思路来解
36+
* 时间复杂度 O(n)
37+
* 空间复杂度 O(n)
38+
* @param {string} s
39+
* @return {number}
40+
*/
41+
function maxPower1(s: string): number {
42+
if (s.length <= 1) return 1;
43+
let maxLength = 1;
44+
let hashTable: Array<{ len: number }> = [];
45+
46+
// 题目的条件以及上面的判断保证里字符串长度至少是 1
47+
for (let i = 1; i < s.length; i++) {
48+
// 如果当前数字和之前不同,则重置数量为 1
49+
if (s[i] !== s[i - 1]) {
50+
hashTable[i] = { len: 1 };
51+
continue;
52+
}
53+
// 用哈希表来保存每个字符累计的次数
54+
const lastLen = hashTable[i - 1] ? hashTable[i - 1].len : 1;
55+
hashTable[i] = { len: lastLen + 1 };
56+
if (hashTable[i].len > maxLength) {
57+
maxLength = hashTable[i].len;
58+
}
59+
}
60+
61+
return maxLength;
62+
};
63+
// @lc code=end

leetcode/290.word-pattern.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* @lc app=leetcode id=290 lang=typescript
3+
*
4+
* [290] Word Pattern
5+
*/
6+
7+
// @lc code=start
8+
/**
9+
* @description: 哈希表的思路
10+
* 时间复杂度 O(m + n)
11+
* 空间复杂度 O(m + n)
12+
* @param {string} pattern
13+
* @param {string} s
14+
* @return {boolean}
15+
*/
16+
function wordPattern(pattern: string, s: string): boolean {
17+
// 转成数组方便操作
18+
const strArr = s.split(' ');
19+
// 如果字符长度不一致,那么肯定不遵循
20+
if (pattern.length !== strArr.length) return false;
21+
22+
const pat2Word = new Map();
23+
const word2Pat = new Map();
24+
25+
for (let i = 0; i < pattern.length; i++) {
26+
const str = pattern[i];
27+
28+
if ((pat2Word.has(str) && pat2Word.get(str) !== strArr[i]) || (word2Pat.has(strArr[i]) && word2Pat.get(strArr[i]) !== str)) {
29+
return false;
30+
}
31+
pat2Word.set(str, strArr[i]);
32+
word2Pat.set(strArr[i], str);
33+
}
34+
35+
// 遍历完成没有问题,说明验证正确
36+
return true;
37+
};
38+
39+
function wordPattern2(pattern: string, s: string): boolean {
40+
// 转成数组方便操作
41+
const strArr = s.split(' ');
42+
// 如果字符长度不一致,那么肯定不遵循
43+
if (pattern.length !== strArr.length) return false;
44+
45+
const map = new Map();
46+
47+
for (let i = 0; i < pattern.length; i++) {
48+
const str = pattern[i];
49+
50+
if (map.has(str)) {
51+
const strValue = map.get(str);
52+
if (strValue !== strArr[i]) return false;
53+
} else {
54+
// 如果已经保存了这个键值,说明有重复
55+
for (const val of map.values()) {
56+
if (val === strArr[i]) return false;
57+
}
58+
map.set(str, strArr[i]);
59+
}
60+
}
61+
62+
// 遍历完成没有问题,说明验证正确
63+
return true;
64+
};
65+
66+
// @lc code=end

leetcode/31.next-permutation.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* @lc app=leetcode id=31 lang=typescript
3+
*
4+
* [31] Next Permutation
5+
*/
6+
7+
// @lc code=start
8+
/**
9+
Do not return anything, modify nums in-place instead.
10+
*/
11+
/**
12+
* @description: 时间复杂度 O(n),空间复杂度 O(1)
13+
* 核心是找到找到相差最小的两位,进行交换,交换之后再把这位之后的数字进行升序排列
14+
* 这里相差最小的两位指的不是值相差最小,而是索引相差最小,例如 [4, 5, 2, 6, 3, 1]; 交换的是 2 和 3;
15+
* 升序排列保证了取到的值是更大的数中的最小值
16+
* @param {number} nums
17+
* @return {void}
18+
*/
19+
function nextPermutation(nums: number[]): void {
20+
let len= nums.length;
21+
let i = len - 2;
22+
23+
// 循环找出第一个比旁边值小的数
24+
// 也就是 i + 1 之后的数组元素都是降序的
25+
while (i >= 0 && nums[i] >= nums[i + 1]) {
26+
i--;
27+
}
28+
29+
// 当前 i 指向的位数是第一个比右边的数小的数
30+
if (i >= 0) {
31+
// 寻找第一个比 i 对应的数更大的数
32+
let j = len - 1;
33+
while (j >= 0 && nums[i] >= nums[j]) {
34+
j--;
35+
}
36+
swap(nums, i, j);
37+
}
38+
39+
reverse(nums, i + 1);
40+
41+
/**
42+
* @description: 原地交换数组内容
43+
* @param {number} arr
44+
* @param {number} i
45+
* @param {number} j
46+
* @return {void}
47+
*/
48+
function swap(arr: number[], i: number, j: number): void {
49+
[arr[j], arr[i]] = [arr[i], arr[j]];
50+
}
51+
52+
/**
53+
* @description: 双指针进行反转
54+
* !为什么这里可以直接反转,因为 i 那里的循环保证了 i 之后的数据都是降序排列的
55+
* @param {number} arr
56+
* @param {number} start
57+
* @return {void}
58+
*/
59+
function reverse(arr: number[], start: number): void {
60+
let left = start;
61+
let right = arr.length - 1;
62+
while (left < right) {
63+
swap(nums, left, right);
64+
left++;
65+
right--;
66+
}
67+
}
68+
};
69+
// @lc code=end

leetcode/383.ransom-note.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* @lc app=leetcode id=383 lang=typescript
3+
*
4+
* [383] Ransom Note
5+
*/
6+
7+
// @lc code=start
8+
/**
9+
* @description: 哈希表的思路
10+
* 时间复杂度 O(m * n)
11+
* 空间复杂度 O(n)
12+
* @param {string} ransomNote
13+
* @param {string} magazine
14+
* @return {boolean}
15+
*/
16+
function canConstruct(ransomNote: string, magazine: string): boolean {
17+
// 说明肯定有字母没能对应上
18+
if (ransomNote.length > magazine.length) return false;
19+
20+
// 使用额外的数组作为散列表,存储每个字母出现过的位置
21+
const magazineArr = [...magazine];
22+
for (const str of ransomNote) {
23+
let isStrInMagazine = false;
24+
25+
for (let i = 0; i < magazineArr.length; i++) {
26+
// 如果有对应字符,就置空索引对应的值,否则遍历结束都没有的话就直接抛出结果
27+
if (magazineArr[i] === str) {
28+
magazineArr[i] = undefined;
29+
isStrInMagazine = true;
30+
break;
31+
}
32+
}
33+
if (!isStrInMagazine) {
34+
return false;
35+
}
36+
}
37+
38+
// 赎金信遍历完成,说明没有问题
39+
return true;
40+
};
41+
42+
function canConstruct2(ransomNote: string, magazine: string): boolean {
43+
// 说明肯定有字母没能对应上
44+
if (ransomNote.length > magazine.length) return false;
45+
46+
// 使用额外的数组作为散列表,存储每个字母出现过的位置
47+
const magazineArr = [...magazine];
48+
for (const str of ransomNote) {
49+
// 如果原始杂志不包含,则直接返回
50+
if (!magazineArr.includes(str)) {
51+
return false;
52+
}
53+
54+
for (let i = 0; i < magazineArr.length; i++) {
55+
// 如果有对应字符,就置空索引对应的值
56+
if (magazineArr[i] === str) {
57+
magazineArr[i] = undefined;
58+
break;
59+
}
60+
continue;
61+
}
62+
}
63+
64+
return true;
65+
};
66+
// @lc code=end
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* @lc app=leetcode id=387 lang=typescript
3+
*
4+
* [387] First Unique Character in a String
5+
*/
6+
7+
// @lc code=start
8+
/**
9+
* @description: 使用 map 来保存不重复的字符
10+
* 时间复杂度 O(n)
11+
* @param {string} s
12+
* @return {number}
13+
*/
14+
function firstUniqChar(s: string): number {
15+
let obj = {}; // 保存重复的字符
16+
let map = new Map(); // 保存不重复的字符的索引
17+
18+
// 遍历当前字符
19+
for (let i = 0; i < s.length; i++) {
20+
const str = s[i];
21+
if (map.get(str) === undefined && !obj[str]) {
22+
map.set(str, i);
23+
continue;
24+
}
25+
map.delete(str);
26+
obj[str] = true;
27+
}
28+
29+
// 如果栈内一个保存的值都没有,说明全部都是重复的
30+
if (map.size === 0) {
31+
return -1;
32+
}
33+
34+
// 因为 map 的遍历时按照插入顺序的,所以一旦有未重复的值,按照索引顺序也就是插入顺序会排在最前面
35+
// for (const value of map.values()) {
36+
// return value;
37+
// }
38+
// 这个方式来获取 map 的第一个值更加优雅
39+
// 使用迭代器
40+
return map.values().next().value;
41+
};
42+
// @lc code=end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* @lc app=leetcode id=496 lang=typescript
3+
*
4+
* [496] Next Greater Element I
5+
*/
6+
7+
// @lc code=start
8+
/**
9+
* @description: 暴力循环法,时间复杂度 O(n*m)
10+
* 其中 m 是 nums1 的长度,n 是 nums2 的长度。
11+
* @param {number[]} nums1
12+
* @param {number[]} nums2
13+
* @return {number[]}
14+
*/
15+
function nextGreaterElement(nums1: number[], nums2: number[]): number[] {
16+
let res: number[] = [];
17+
18+
for (const num of nums1) {
19+
let foundSame = false;
20+
let foundBigger = false;
21+
// 在父数组中查找更大的值
22+
for (let i = 0; i < nums2.length; i++) {
23+
const parentNum = nums2[i];
24+
if (parentNum === num) {
25+
foundSame = true;
26+
continue;
27+
}
28+
// 结果不相等时继续判断是否有更大的值
29+
if (parentNum !== num) {
30+
if (foundSame) {
31+
if (parentNum > num) {
32+
res.push(parentNum);
33+
foundBigger = true;
34+
break;
35+
}
36+
}
37+
continue;
38+
}
39+
}
40+
if (!foundBigger) {
41+
res.push(-1);
42+
}
43+
}
44+
45+
return res;
46+
};
47+
// @lc code=end

0 commit comments

Comments
 (0)