From 4eeebf3fc1dbb22ad6eb4c34125a8c4875f529a4 Mon Sep 17 00:00:00 2001 From: tolluset Date: Tue, 13 Aug 2024 01:17:59 +0900 Subject: [PATCH 01/10] solve: contains duplicate --- contains-duplicate/tolluset.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 contains-duplicate/tolluset.ts diff --git a/contains-duplicate/tolluset.ts b/contains-duplicate/tolluset.ts new file mode 100644 index 000000000..c1b31092b --- /dev/null +++ b/contains-duplicate/tolluset.ts @@ -0,0 +1,7 @@ +/* + * TC: O(n) + * SC: O(n) + * */ +function containsDuplicate(nums: number[]): boolean { + return nums.length !== new Set(nums).size; +} From c4397be963ede8d15ad5502561b13d59bebc7943 Mon Sep 17 00:00:00 2001 From: tolluset Date: Tue, 13 Aug 2024 01:23:19 +0900 Subject: [PATCH 02/10] solve: number of 1 bits --- number-of-1-bits/tolluset.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 number-of-1-bits/tolluset.ts diff --git a/number-of-1-bits/tolluset.ts b/number-of-1-bits/tolluset.ts new file mode 100644 index 000000000..1536cff88 --- /dev/null +++ b/number-of-1-bits/tolluset.ts @@ -0,0 +1,10 @@ +/* + * TC: O(logn) + * SC: O(logn) + * */ +function hammingWeight(n: number): number { + return n + .toString(2) + .split("") + .filter((s) => s === "1").length; +} From a87dd08b5cf54a5798f28e5f4b03adff561db38a Mon Sep 17 00:00:00 2001 From: tolluset Date: Tue, 13 Aug 2024 02:42:48 +0900 Subject: [PATCH 03/10] solve: top k frequent elements --- top-k-frequent-elements/tolluset.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 top-k-frequent-elements/tolluset.ts diff --git a/top-k-frequent-elements/tolluset.ts b/top-k-frequent-elements/tolluset.ts new file mode 100644 index 000000000..d828c4ec6 --- /dev/null +++ b/top-k-frequent-elements/tolluset.ts @@ -0,0 +1,27 @@ +type Nums = [number, number][]; + +/* + * TC: O(nlogn) + * SC: O(n) + * */ +function topKFrequent(nums: number[], k: number): number[] { + const counting = (arr: number[]) => + arr.reduce((acc, n) => { + const val = acc.get(n) ?? 0; + acc.set(n, val + 1); + return acc; + }, new Map()); + + const toValues = (map: Map) => Array.from(map.entries()); + + const sorting = (arr: Nums) => arr.sort((a, b) => b[1] - a[1]); + + const getK = (arr: Nums, k: number) => arr.slice(0, k).map((v) => v[0]); + + return pipe(counting, toValues, sorting, (arr: Nums) => getK(arr, k))(nums); +} + +const pipe = + (...fns: Function[]) => + (x: any) => + fns.reduce((v, f) => f(v), x); From a093b401f1ab1335b94a90f11716ac27e2799be7 Mon Sep 17 00:00:00 2001 From: tolluset Date: Tue, 13 Aug 2024 04:40:21 +0900 Subject: [PATCH 04/10] solve: kth smallest element in a bst --- kth-smallest-element-in-a-bst/tolluset.ts | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 kth-smallest-element-in-a-bst/tolluset.ts diff --git a/kth-smallest-element-in-a-bst/tolluset.ts b/kth-smallest-element-in-a-bst/tolluset.ts new file mode 100644 index 000000000..2534ca3dc --- /dev/null +++ b/kth-smallest-element-in-a-bst/tolluset.ts @@ -0,0 +1,42 @@ +class TreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = val === undefined ? 0 : val; + this.left = left === undefined ? null : left; + this.right = right === undefined ? null : right; + } +} + +/* + * TC: O(n) + * SC: O(n) + * */ +function kthSmallest(root: TreeNode, k: number): number { + let count = 0; + let result: null | number = null; + + const inOrder = (node: TreeNode | null) => { + if (!node || result !== null) { + return false; + } + + if (inOrder(node.left)) { + return true; + } + + count++; + + if (count === k) { + result = node.val; + return true; + } + + inOrder(node.right); + }; + + inOrder(root); + + return result!; +} From 9d52d3e3246c4f65c971fa7acb3dd40f126e8bcb Mon Sep 17 00:00:00 2001 From: tolluset Date: Tue, 13 Aug 2024 22:37:49 +0900 Subject: [PATCH 05/10] solve: palindromic substrings --- palindromic-substrings/tolluset.ts | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 palindromic-substrings/tolluset.ts diff --git a/palindromic-substrings/tolluset.ts b/palindromic-substrings/tolluset.ts new file mode 100644 index 000000000..05c937a71 --- /dev/null +++ b/palindromic-substrings/tolluset.ts @@ -0,0 +1,59 @@ +/* + * TC: O(n) + * SC: O(n) + * */ +function countSubstrings(s: string): number { + const t = "#" + s.split("").join("#") + "#"; + const n = t.length; + const p = new Array(n).fill(0); + let center = 0, + right = 0, + l = 0; + + const mirror = (i: number, p: number[], c: number, r: number) => { + return Math.min(r - i, p[c * 2 - i]); + }; + + const isRightBound = (i: number, p: number[], n: number) => { + return i + p[i] + 1 < n; + }; + + const isLeftBound = (i: number, p: number[]) => { + return i - p[i] - 1 >= 0; + }; + + const isPalindrome = (i: number, p: number[], t: string) => { + return t[i + p[i] + 1] === t[i - p[i] - 1]; + }; + + const isLongest = (i: number, p: number[], r: number) => { + return i + p[i] > r; + }; + + const calcTotal = (i: number, p: number[]) => { + return Math.floor((p[i] + 1) / 2); + }; + + for (let i = 0; i < n; i++) { + if (i < right) { + p[i] = mirror(i, p, center, right); + } + + while ( + isRightBound(i, p, n) && + isLeftBound(i, p) && + isPalindrome(i, p, t) + ) { + p[i]++; + } + + if (isLongest(i, p, right)) { + center = i; + right = i + p[i]; + } + + l += calcTotal(i, p); + } + + return l; +} From 29ec5eb1c8b0786774e891186b63a04eb85d544b Mon Sep 17 00:00:00 2001 From: tolluset Date: Thu, 15 Aug 2024 23:57:34 +0900 Subject: [PATCH 06/10] refacotr: apply review --- palindromic-substrings/tolluset.ts | 56 ++++++++++-------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/palindromic-substrings/tolluset.ts b/palindromic-substrings/tolluset.ts index 05c937a71..c48396e21 100644 --- a/palindromic-substrings/tolluset.ts +++ b/palindromic-substrings/tolluset.ts @@ -3,57 +3,37 @@ * SC: O(n) * */ function countSubstrings(s: string): number { - const t = "#" + s.split("").join("#") + "#"; - const n = t.length; - const p = new Array(n).fill(0); + const str = "#" + s.split("").join("#") + "#"; + const len = str.length; + const pit = new Array(len).fill(0); let center = 0, right = 0, - l = 0; + result = 0; - const mirror = (i: number, p: number[], c: number, r: number) => { - return Math.min(r - i, p[c * 2 - i]); - }; - - const isRightBound = (i: number, p: number[], n: number) => { - return i + p[i] + 1 < n; - }; - - const isLeftBound = (i: number, p: number[]) => { - return i - p[i] - 1 >= 0; - }; - - const isPalindrome = (i: number, p: number[], t: string) => { - return t[i + p[i] + 1] === t[i - p[i] - 1]; - }; - - const isLongest = (i: number, p: number[], r: number) => { - return i + p[i] > r; - }; - - const calcTotal = (i: number, p: number[]) => { - return Math.floor((p[i] + 1) / 2); - }; - - for (let i = 0; i < n; i++) { + for (let i = 0; i < len; i++) { + // Set pit[i] if (i < right) { - p[i] = mirror(i, p, center, right); + pit[i] = Math.min(right - i, pit[center * 2 - i]); } + // Expand around i while ( - isRightBound(i, p, n) && - isLeftBound(i, p) && - isPalindrome(i, p, t) + i + pit[i] + 1 < len && + i - pit[i] - 1 >= 0 && + str[i + pit[i] + 1] === str[i - pit[i] - 1] ) { - p[i]++; + pit[i]++; } - if (isLongest(i, p, right)) { + // Update center and right + if (i + pit[i] > right) { center = i; - right = i + p[i]; + right = i + pit[i]; } - l += calcTotal(i, p); + // Add to result + result += Math.floor((pit[i] + 1) / 2); } - return l; + return result; } From f19566a0ddc02304b8f6f84b5d296cca88a3edd5 Mon Sep 17 00:00:00 2001 From: tolluset Date: Fri, 16 Aug 2024 01:35:14 +0900 Subject: [PATCH 07/10] refacotr: add more detail description --- palindromic-substrings/tolluset.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/palindromic-substrings/tolluset.ts b/palindromic-substrings/tolluset.ts index c48396e21..71d5f3d1c 100644 --- a/palindromic-substrings/tolluset.ts +++ b/palindromic-substrings/tolluset.ts @@ -11,12 +11,12 @@ function countSubstrings(s: string): number { result = 0; for (let i = 0; i < len; i++) { - // Set pit[i] + // If i is within the rightmost center, copy the pit value from the mirror if (i < right) { pit[i] = Math.min(right - i, pit[center * 2 - i]); } - // Expand around i + // Expand around i until it's not a palindrome and not over left or right while ( i + pit[i] + 1 < len && i - pit[i] - 1 >= 0 && @@ -25,13 +25,13 @@ function countSubstrings(s: string): number { pit[i]++; } - // Update center and right + // If pit value is the new rightmost center, update center and right if (i + pit[i] > right) { center = i; right = i + pit[i]; } - // Add to result + // Add the number of palindromes with center i to the result result += Math.floor((pit[i] + 1) / 2); } From 2ad5c0efa0ff36f40325c4aa728d947b37863280 Mon Sep 17 00:00:00 2001 From: tolluset Date: Fri, 16 Aug 2024 01:58:54 +0900 Subject: [PATCH 08/10] refacotr: rename variables more clearly --- palindromic-substrings/tolluset.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/palindromic-substrings/tolluset.ts b/palindromic-substrings/tolluset.ts index 71d5f3d1c..9fe20d979 100644 --- a/palindromic-substrings/tolluset.ts +++ b/palindromic-substrings/tolluset.ts @@ -5,35 +5,35 @@ function countSubstrings(s: string): number { const str = "#" + s.split("").join("#") + "#"; const len = str.length; - const pit = new Array(len).fill(0); + const pal = new Array(len).fill(0); let center = 0, - right = 0, - result = 0; + radius = 0, + total = 0; for (let i = 0; i < len; i++) { - // If i is within the rightmost center, copy the pit value from the mirror - if (i < right) { - pit[i] = Math.min(right - i, pit[center * 2 - i]); + // If i is within the rightmost center, copy the palindromes value from the mirror + if (i < radius) { + pal[i] = Math.min(radius - i, pal[center * 2 - i]); } // Expand around i until it's not a palindrome and not over left or right while ( - i + pit[i] + 1 < len && - i - pit[i] - 1 >= 0 && - str[i + pit[i] + 1] === str[i - pit[i] - 1] + i + pal[i] + 1 < len && + i - pal[i] - 1 >= 0 && + str[i + pal[i] + 1] === str[i - pal[i] - 1] ) { - pit[i]++; + pal[i]++; } - // If pit value is the new rightmost center, update center and right - if (i + pit[i] > right) { + // If palindromes value is the new rightmost center, update center and right + if (i + pal[i] > radius) { center = i; - right = i + pit[i]; + radius = i + pal[i]; } // Add the number of palindromes with center i to the result - result += Math.floor((pit[i] + 1) / 2); + total += Math.floor((pal[i] + 1) / 2); } - return result; + return total; } From 381f802f24abdf73cc8bfdf1c9c2aca51db98579 Mon Sep 17 00:00:00 2001 From: tolluset Date: Fri, 16 Aug 2024 02:11:57 +0900 Subject: [PATCH 09/10] refacotr: rename variables more descriptive --- palindromic-substrings/tolluset.ts | 38 +++++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/palindromic-substrings/tolluset.ts b/palindromic-substrings/tolluset.ts index 9fe20d979..42432d24f 100644 --- a/palindromic-substrings/tolluset.ts +++ b/palindromic-substrings/tolluset.ts @@ -3,36 +3,40 @@ * SC: O(n) * */ function countSubstrings(s: string): number { - const str = "#" + s.split("").join("#") + "#"; - const len = str.length; - const pal = new Array(len).fill(0); - let center = 0, - radius = 0, - total = 0; + const transformedString = "#" + s.split("").join("#") + "#"; + const transformedStringLength = transformedString.length; + const palindromeLengths = new Array(transformedStringLength).fill(0); + let currentCenter = 0, + rightBoundary = 0, + totalPalindromeCount = 0; - for (let i = 0; i < len; i++) { + for (let i = 0; i < transformedStringLength; i++) { // If i is within the rightmost center, copy the palindromes value from the mirror - if (i < radius) { - pal[i] = Math.min(radius - i, pal[center * 2 - i]); + if (i < rightBoundary) { + palindromeLengths[i] = Math.min( + rightBoundary - i, + palindromeLengths[currentCenter * 2 - i], + ); } // Expand around i until it's not a palindrome and not over left or right while ( - i + pal[i] + 1 < len && - i - pal[i] - 1 >= 0 && - str[i + pal[i] + 1] === str[i - pal[i] - 1] + i + palindromeLengths[i] + 1 < transformedStringLength && + i - palindromeLengths[i] - 1 >= 0 && + transformedString[i + palindromeLengths[i] + 1] === + transformedString[i - palindromeLengths[i] - 1] ) { - pal[i]++; + palindromeLengths[i]++; } // If palindromes value is the new rightmost center, update center and right - if (i + pal[i] > radius) { - center = i; - radius = i + pal[i]; + if (i + palindromeLengths[i] > radius) { + currentCenter = i; + rightBoundary = i + palindromeLengths[i]; } // Add the number of palindromes with center i to the result - total += Math.floor((pal[i] + 1) / 2); + total += Math.floor((palindromeLengths[i] + 1) / 2); } return total; From 9607c5d0841c8decca070d4b3d34cf8a02933303 Mon Sep 17 00:00:00 2001 From: tolluset Date: Sat, 17 Aug 2024 15:41:05 +0900 Subject: [PATCH 10/10] refactor: make return simple --- top-k-frequent-elements/tolluset.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/top-k-frequent-elements/tolluset.ts b/top-k-frequent-elements/tolluset.ts index d828c4ec6..7aa69e8f6 100644 --- a/top-k-frequent-elements/tolluset.ts +++ b/top-k-frequent-elements/tolluset.ts @@ -6,11 +6,10 @@ type Nums = [number, number][]; * */ function topKFrequent(nums: number[], k: number): number[] { const counting = (arr: number[]) => - arr.reduce((acc, n) => { - const val = acc.get(n) ?? 0; - acc.set(n, val + 1); - return acc; - }, new Map()); + arr.reduce( + (acc, n) => acc.set(n, (acc.get(n) ?? 0) + 1), + new Map(), + ); const toValues = (map: Map) => Array.from(map.entries());