Skip to content

Commit cc71bd8

Browse files
committed
feat: leetcode contest 311 & 312
1 parent 156e823 commit cc71bd8

9 files changed

+267
-4
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @param {number} n
3+
* @return {number}
4+
*/
5+
const smallestEvenMultiple = function (n) {
6+
if (n % 2 === 0) return n
7+
return 2 * n
8+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* @param {string} s
3+
* @return {number}
4+
*/
5+
const longestContinuousSubstring = function (s) {
6+
s = s.split('').map((x) => x.charCodeAt(0) - 'a'.charCodeAt(0))
7+
const n = s.length
8+
let ans = 0
9+
for (let i = 0; i < n;) {
10+
let j = i
11+
while (j < n && (j === i || s[j] - s[j - 1] === 1)) j++
12+
ans = Math.max(ans, j - i)
13+
i = j
14+
}
15+
return ans
16+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* function TreeNode(val, left, right) {
4+
* this.val = (val===undefined ? 0 : val)
5+
* this.left = (left===undefined ? null : left)
6+
* this.right = (right===undefined ? null : right)
7+
* }
8+
*/
9+
/**
10+
* @param {TreeNode} root
11+
* @return {TreeNode}
12+
*/
13+
const reverseOddLevels = function (root) {
14+
let q = [[root, 0]]
15+
const a = []; let idx = 0
16+
while (q.length) {
17+
const [node, dep] = q.pop()
18+
a.push(node.val)
19+
if (node.right) q.push([node.right, dep + 1])
20+
if (node.left) q.push([node.left, dep + 1])
21+
}
22+
q = [[root, 0]]
23+
while (q.length) {
24+
const [node, dep] = q.pop()
25+
if (dep % 2 === 1) node.val = a[idx]
26+
idx++
27+
if (node.left) q.push([node.left, dep + 1])
28+
if (node.right) q.push([node.right, dep + 1])
29+
}
30+
return root
31+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
export {}
2+
class TrieNode {
3+
char: string
4+
count: number = 0
5+
countPrefix: number = 0
6+
children: { [key: string]: TrieNode | undefined } = {}
7+
constructor (char: string) {
8+
this.char = char
9+
}
10+
};
11+
class Trie {
12+
trie: TrieNode
13+
/**
14+
* @description Initialize the trie
15+
*/
16+
constructor () {
17+
this.trie = new TrieNode('/')
18+
}
19+
20+
/**
21+
* @description Insert strings into the trie
22+
* @param str the string to be inserted
23+
* @param count number of `str` to be inserted, can be negative for deleting x from the trie
24+
*/
25+
insert (str: string, count: number = 1): void {
26+
let cur = this.trie
27+
for (const char of str) {
28+
cur.children[char] ??= new TrieNode(char)
29+
cur = cur.children[char]!
30+
cur.countPrefix += count
31+
}
32+
cur.count += count
33+
}
34+
35+
/**
36+
* Traverse the trie with a callback function
37+
* @param str An input string
38+
* @param callbackfn A callback function. traverse calls the callbackfn function one time for each char in `str`, however it may skip ending chars in str if the trie has no children to go deeper, the returned char from callbackfn will be used as the direction of traversing
39+
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value
40+
*/
41+
traverse (str: string, callbackfn: (char: string, idx: number, node: TrieNode) => string, thisArg?: any): void {
42+
let cur = this.trie
43+
for (let i = 0; i < str.length; i++) {
44+
const retChar = callbackfn.call(thisArg, str[i], i, cur)
45+
const tmp = cur.children[retChar]
46+
if (!tmp || tmp.countPrefix <= 0) return
47+
cur = tmp
48+
}
49+
}
50+
51+
/**
52+
* @description Search a string in the trie
53+
* @returns Number of `str` in the trie
54+
*/
55+
count (str: string): number {
56+
let ans = 0
57+
this.traverse(str, (char, idx, node) => {
58+
const nextNode = node.children[char]
59+
if (idx === str.length - 1 && nextNode) {
60+
ans = nextNode.count
61+
}
62+
return char
63+
})
64+
return ans
65+
}
66+
67+
/**
68+
* @description Search a string in the trie
69+
* @returns Number of prefix of `str` in the trie
70+
*/
71+
countPrefix (str: string): number {
72+
let ans = 0
73+
this.traverse(str, (char, idx, node) => {
74+
const nextNode = node.children[char]
75+
ans += nextNode?.countPrefix ?? 0
76+
return char
77+
})
78+
return ans
79+
}
80+
};
81+
82+
function sumPrefixScores (words: string[]): number[] {
83+
const trie = new Trie()
84+
const ans = []
85+
for (const w of words) {
86+
trie.insert(w, 1)
87+
}
88+
for (const w of words) {
89+
ans.push(trie.countPrefix(w))
90+
}
91+
return ans
92+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @param {string[]} names
3+
* @param {number[]} heights
4+
* @return {string[]}
5+
*/
6+
const sortPeople = function (names, heights) {
7+
return names.map((x, idx) => [x, heights[idx]]).sort((a, b) => b[1] - a[1]).map(x => x[0])
8+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number}
4+
*/
5+
const longestSubarray = function (nums) {
6+
const max = Math.max(...nums)
7+
let maxLen = 0
8+
const n = nums.length
9+
for (let i = 0; i < n; i++) {
10+
let j = i
11+
while (j < n && nums[j] === nums[i]) j++
12+
if (nums[i] === max) {
13+
const len = j - i
14+
maxLen = Math.max(maxLen, len)
15+
}
16+
i = j - 1
17+
}
18+
return maxLen
19+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @param {number[]} nums
3+
* @param {number} k
4+
* @return {number[]}
5+
*/
6+
const goodIndices = function (nums, k) {
7+
const n = nums.length
8+
const ans = []
9+
const left = []; const right = []
10+
// nums[-1] = 1e10, nums[n] = 1e10
11+
for (let i = 0; i < n; i++) {
12+
left[i] = i
13+
let j = i + 1
14+
while (j < n && nums[j] <= nums[j - 1]) left[j] = i, j++
15+
i = j - 1
16+
}
17+
for (let i = n - 1; i >= 0; i--) {
18+
right[i] = i
19+
let j = i - 1
20+
while (j >= 0 && nums[j] <= nums[j + 1]) right[j] = i, j--
21+
i = j + 1
22+
}
23+
// console.log(left, right)
24+
for (let i = k; i < n - k; i++) {
25+
const a = i - 1; const b = i + 1
26+
// console.log(i, a, b, left[a], a-k, right[b], b+k, a-left[a]+1>=k&&right[b]-b+k>=k)
27+
if (a - left[a] + 1 >= k && right[b] - b + 1 >= k) ans.push(i)
28+
}
29+
return ans
30+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @param {number[]} vals
3+
* @param {number[][]} edges
4+
* @return {number}
5+
*/
6+
const numberOfGoodPaths = function (vals, edges) {
7+
const n = vals.length
8+
const fa = Array(n).fill(0).map((_, idx) => idx)
9+
const sz = Array(n).fill(1)
10+
const cnts = Array(n).fill(0).map((_, idx) => ({ [vals[idx]]: 1 }))
11+
edges = edges.map((e, idx) => [...e, Math.max(vals[e[0]], vals[e[1]])]).sort((a, b) => a[2] - b[2])
12+
const m = edges.length
13+
let ans = n
14+
const cnt = {}
15+
const get = (x) => {
16+
if (x === fa[x]) return x
17+
return fa[x] = get(fa[x])
18+
}
19+
const merge = (x, y) => {
20+
let fx = get(x); let fy = get(y)
21+
if (fx === fy) return
22+
if (sz[fx] > sz[fy]) [fx, fy] = [fy, fx]
23+
fa[fx] = fy
24+
sz[fy] += sz[fx]
25+
const cx = cnts[fx]; const cy = cnts[fy]
26+
// 必须要用按秩合并,否则这里的复制次数太多会导致 TLE/MLE
27+
for (const [k, v] of Object.entries(cx)) {
28+
cy[k] ??= 0
29+
cy[k] += v
30+
}
31+
// console.log(x, y, cnts[fy])
32+
}
33+
for (let i = 0; i < m; i++) {
34+
let j = i
35+
const p = new Set(); const t = edges[i][2]
36+
while (j < m && edges[j][2] === edges[i][2]) {
37+
merge(edges[j][0], edges[j][1])
38+
j++
39+
}
40+
for (let k = i; k < j; k++) {
41+
if (vals[edges[k][0]] === t) {
42+
p.add(get(edges[k][0]))
43+
}
44+
if (vals[edges[k][1]] === t) {
45+
p.add(get(edges[k][1]))
46+
}
47+
}
48+
// console.log(t, p)
49+
for (const x of p) {
50+
// console.log(x, t, cnts[x][t])
51+
const c = cnts[x][t]
52+
ans += c * (c - 1) / 2
53+
}
54+
55+
i = j - 1
56+
}
57+
return ans
58+
}

leetcode/残酷刷题/2402. Meeting Rooms III.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
typedef pair<long long, int> PII;
22
class Solution {
3-
public:
4-
int mostBooked(int n, vector<vector<int>>& meetings) {
5-
sort(meetings.begin(), meetings.end(), [](auto &m1, auto &m2){
3+
public:
4+
int mostBooked(int n, vector<vector<int>> &meetings) {
5+
sort(meetings.begin(), meetings.end(), [](auto &m1, auto &m2) {
66
return m1[0] < m2[0];
77
});
88
vector<int> cnt(n, 0);
@@ -20,9 +20,10 @@ class Solution {
2020
if (!free.size()) {
2121
auto t = pq.top().first;
2222
// 这里不能把所有 t 时刻结束的都放入 free
23+
// https://leetcode.cn/problems/meeting-rooms-iii/solution/shuang-dui-mo-ni-pythonjavacgo-by-endles-ctwc/1738683
2324
free.insert(pq.top().second);
2425
pq.pop();
25-
e = e-s+t, s = t;
26+
e = e - s + t, s = t;
2627
}
2728
auto it = free.begin();
2829
pq.push({e, *it});

0 commit comments

Comments
 (0)