Skip to content

Commit 744d832

Browse files
committed
initial commit
0 parents  commit 744d832

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1985
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

LCA-binary.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// class TreeNode {
2+
// val: number;
3+
// left: TreeNode | null;
4+
// right: TreeNode | null;
5+
// constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
6+
// this.val = val === undefined ? 0 : val;
7+
// this.left = left === undefined ? null : left;
8+
// this.right = right === undefined ? null : right;
9+
// }
10+
// }
11+
12+
/**
13+
DFS approach
14+
15+
1. DFS find path p & path q
16+
2. The last common of the path p & path q is the LCA
17+
18+
**/
19+
20+
function lowestCommonAncestor(
21+
root: TreeNode | null,
22+
p: TreeNode | null,
23+
q: TreeNode | null
24+
): TreeNode | null {
25+
const dfsPath = (targetNode: TreeNode): number[] => {
26+
const path: number[] = [];
27+
let ret: number[] = [];
28+
const dfs = (curr = root): void => {
29+
if (curr === null) return;
30+
if (curr === targetNode) {
31+
ret = path;
32+
return;
33+
}
34+
if (ret.length !== 0) return;
35+
path.push(curr.val);
36+
dfs(curr.left);
37+
dfs(curr.right);
38+
path.pop();
39+
};
40+
dfs();
41+
return ret;
42+
};
43+
const pathP = dfsPath(p);
44+
const pathQ = dfsPath(q);
45+
46+
let lastCommonVal: number = root.val;
47+
while (pathP.length !== 0 && pathQ.length !== 0) {
48+
const pFirst = pathP.shift();
49+
const qFirst = pathQ.shift();
50+
if (pFirst !== qFirst) break;
51+
pFirst === qFirst && (lastCommonVal = pFirst);
52+
}
53+
54+
// BFS find node
55+
const findByVal = (val): TreeNode => {
56+
const queue: TreeNode[] = [];
57+
queue.push(root);
58+
while (queue.length !== 0) {
59+
let len = queue.length;
60+
while (len-- !== 0) {
61+
const curr = queue.shift();
62+
if (curr.val === val) return curr;
63+
curr.left && queue.push(curr.left);
64+
curr.right && queue.push(curr.right);
65+
}
66+
}
67+
};
68+
return findByVal(lastCommonVal);
69+
}

Trapping-Rain-Water.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
Using stack solve this
3+
4+
1. Kepp a stack [], which keep push [value, index]
5+
2. Iteration
6+
check the stack end
7+
1. if end.value < curr.value
8+
1. pop end
9+
2. diffVal = endVal - lastVal
10+
3. diffIdx = curIdx - endIdx
11+
3. diffVal * (diffIdx - 1)
12+
2. else
13+
1. diffVal = curVal - lastVal ----> now use the curVal
14+
2. diffIdx = curIdx - endIdx
15+
3. diffVal * (diffIdx - 1)
16+
4. push curr
17+
18+
**/
19+
20+
function trap(height: number[]): number {
21+
let ans: number = 0;
22+
let lastVal: number = 0;
23+
const stack: [number, number][] = [];
24+
for (let i = 0; i < height.length; i++) {
25+
const curVal = height[i];
26+
const curIdx = i;
27+
if (stack.length === 0) stack.push([curVal, curIdx]);
28+
else {
29+
while (stack.length !== 0 && stack[stack.length - 1][0] <= curVal) {
30+
const end = stack.pop();
31+
const [endVal, endIdx] = end;
32+
const diffIdx = curIdx - endIdx;
33+
const diffVal = endVal - lastVal;
34+
ans += diffVal * (diffIdx - 1);
35+
lastVal = endVal;
36+
}
37+
if (stack.length !== 0) {
38+
const end = stack[stack.length - 1];
39+
const [endVal, endIdx] = end;
40+
const diffIdx = curIdx - endIdx;
41+
const diffVal = curVal - lastVal;
42+
ans += diffVal * (diffIdx - 1);
43+
}
44+
stack.push([curVal, curIdx]);
45+
}
46+
}
47+
return ans;
48+
}

add-two-numbers.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
function addTwoNumbers(
2+
l1: ListNode | null,
3+
l2: ListNode | null
4+
): ListNode | null {
5+
let root = l1;
6+
let carry = 0;
7+
while (l1 !== null && l2 !== null) {
8+
l1.val = carry + l1.val + l2.val;
9+
carry = 0;
10+
11+
// handle carry
12+
if (l1.val > 9) {
13+
carry = Math.floor(l1.val / 10);
14+
l1.val %= 10;
15+
}
16+
17+
// extend the shortest list
18+
if (l1.next === null && l2.next !== null) l1.next = new ListNode(0);
19+
if (l1.next !== null && l2.next === null) l2.next = new ListNode(0);
20+
21+
// [corner case] handle the lastest carry case
22+
if (l1.next === null && l2.next === null && carry !== 0)
23+
l1.next = new ListNode(carry);
24+
25+
l1 = l1.next;
26+
l2 = l2.next;
27+
}
28+
return root;
29+
}

count-complete-tree.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* class TreeNode {
4+
* val: number
5+
* left: TreeNode | null
6+
* right: TreeNode | null
7+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
8+
* this.val = (val===undefined ? 0 : val)
9+
* this.left = (left===undefined ? null : left)
10+
* this.right = (right===undefined ? null : right)
11+
* }
12+
* }
13+
*/
14+
15+
function countNodes(root: TreeNode | null): number {
16+
if (root === null) return 0;
17+
18+
const getHeight = (node: TreeNode | null): number => {
19+
let height = 0;
20+
let ptr = node;
21+
while (ptr !== null) {
22+
height++;
23+
ptr = ptr.left;
24+
}
25+
return height;
26+
};
27+
const isFullTree = (node: TreeNode | null): boolean => {
28+
if (node === null) return true;
29+
let left = node.left,
30+
right = node.right;
31+
while (left !== null && right !== null) {
32+
left = left.left;
33+
right = right.right;
34+
}
35+
return left === right; // should be null in same time
36+
};
37+
const traversal = (node: TreeNode | null, lo: number, hi: number): number => {
38+
let mi = Math.floor((lo + hi) / 2);
39+
if (isFullTree(node)) return hi;
40+
if (!isFullTree(node.right)) return traversal(node.right, mi + 1, hi);
41+
if (!isFullTree(node.left)) return traversal(node.left, lo, mi);
42+
43+
return mi;
44+
};
45+
46+
const treeHeight = getHeight(root);
47+
return traversal(root, 2 ** (treeHeight - 1), 2 ** treeHeight - 1);
48+
}

decode-string.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
function decodeString(s: string): string {
2+
let res: string = "";
3+
let numStr: string = "";
4+
const stack: [string, string][] = [];
5+
6+
for (let i = 0; i < s.length; i++) {
7+
const ch = s.charAt(i);
8+
if (
9+
ch.charCodeAt(0) - "a".charCodeAt(0) >= 0 &&
10+
ch.charCodeAt(0) - "a".charCodeAt(0) < 26
11+
) {
12+
res += ch;
13+
}
14+
if (!Number.isNaN(Number(ch))) {
15+
numStr += ch;
16+
}
17+
18+
if (ch === "[") {
19+
stack.push([res, numStr]);
20+
}
21+
if (ch === "]") {
22+
const [_res, _numStr] = stack.pop();
23+
res = _res + res.repeat(Number(_numStr));
24+
}
25+
}
26+
27+
return res;
28+
}

find-min.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const findIndex = (
2+
arr: number[],
3+
fn: (val: number, index: number) => number
4+
) => {
5+
let lo = 0,
6+
hi = arr.length - 1;
7+
while (lo <= hi) {
8+
const mi = Math.floor((lo + hi) / 2);
9+
if (fn(arr[mi], mi) === 0) return mi;
10+
if (fn(arr[mi], mi) < 0) lo = mi + 1;
11+
if (fn(arr[mi], mi) > 0) hi = mi - 1;
12+
}
13+
return lo - 1;
14+
};
15+
16+
function findMin(nums: number[]): number {
17+
const maxIdx = findIndex(nums, (val: number, index: number): number => {
18+
if (val < nums[0]) return 1;
19+
else return -1;
20+
});
21+
22+
return (maxIdx + 1) % nums.length;
23+
}

find-positive-solution.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* // This is the CustomFunction's API interface.
3+
* // You should not implement it, or speculate about its implementation
4+
* class CustomFunction {
5+
* f(x: number, y: number): number {}
6+
* }
7+
*/
8+
9+
function findSolution(customfunction: CustomFunction, z: number): number[][] {
10+
const f = customfunction.f.bind(customfunction); // somehow only typescript got the context error
11+
const ret: number[][] = [];
12+
for (let i = 1; i <= 1000; i++) {
13+
for (let j = 1; j <= 1000; j++) {
14+
if (f(i, j) > z) break;
15+
if (f(i, j) === z) ret.push([i, j]);
16+
}
17+
}
18+
19+
return ret;
20+
}

find_island.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
Let's iteration and check their adjacency node if they are both '1'
3+
1. Iteration from [0,0] to [m,n]
4+
2. For [i,j], if it's '1' check the [i+1,j] [i,j+1]
5+
1. if yes, then union(find(i,j), find(i+1,j))
6+
3. Before access the arry, notice the corner case
7+
8+
Let's define the union/find structure
9+
1. mxn table
10+
2. find(i,j)
11+
1. if(table[i][j] is empty then table[i][j] = [i,j];
12+
1. generateId: just increase the unique key
13+
2. else return find(table[i][j])
14+
3. union(a,b)
15+
1. find(a) = find(b);
16+
**/
17+
18+
function numIslands(grid: string[][]): number {
19+
const m = grid.length;
20+
const n = grid[0].length;
21+
22+
const parent: number[][][] = Array.from({ length: m }, (val) =>
23+
Array.from({ length: n }, (val) => [-1, -1])
24+
);
25+
26+
const find = (...u: number[]): number[] => {
27+
const [i, j] = u;
28+
const [pI, pJ] = parent[i][j];
29+
if (pI === -1 && pJ === -1) {
30+
parent[i][j] = [i, j];
31+
return [i, j];
32+
} else {
33+
return pI === i && pJ === j ? [i, j] : find(pI, pJ);
34+
}
35+
};
36+
const union = (u1: number[], u2: number[]): void => {
37+
console.log(u1, u2);
38+
const p1 = find(...u1);
39+
const [i, j] = find(...u2);
40+
parent[i][j] = p1;
41+
};
42+
43+
for (let i = 0; i < m; i++) {
44+
for (let j = 0; j < n; j++) {
45+
if (grid[i][j] === "0") continue;
46+
if (i + 1 !== m && j + 1 !== n && grid[i + 1][j + 1] === "1")
47+
union([i, j], [i + 1, j + 1]);
48+
if (i + 1 !== m && grid[i + 1][j] === "1") union([i, j], [i + 1, j]);
49+
if (j + 1 !== n && grid[i][j + 1] === "1") union([i, j], [i, j + 1]);
50+
}
51+
}
52+
const collections: Set<string> = new Set();
53+
for (let i = 0; i < m; i++) {
54+
for (let j = 0; j < n; j++) {
55+
const p = parent[i][j];
56+
if (p[0] === -1 && p[1] === -1) continue;
57+
collections.add(`${p[0]}-${p[1]}`);
58+
}
59+
}
60+
return collections.size;
61+
}

first-missing-positive.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
function firstMissingPositive(nums: number[]): number {
2+
let i = 0;
3+
while (i < nums.length) {
4+
const idx = nums[i];
5+
6+
// we don't care
7+
if (idx < 1 || idx >= nums.length) {
8+
i++;
9+
continue;
10+
}
11+
12+
// prevent infinite loop
13+
if (nums[i] === nums[idx - 1]) {
14+
i++;
15+
continue;
16+
}
17+
18+
[nums[idx - 1], nums[i]] = [nums[i], nums[idx - 1]];
19+
}
20+
21+
for (let i = 0; i < nums.length; i++) {
22+
if (nums[i] !== i + 1) return i + 1;
23+
}
24+
return nums.length + 1;
25+
}

0 commit comments

Comments
 (0)