From 2ee18ce48cf191a43c833be4788bff7e6b54d8a4 Mon Sep 17 00:00:00 2001 From: HC-kang Date: Mon, 12 Aug 2024 09:14:28 +0900 Subject: [PATCH 1/7] Feat: add solution for 217 --- contains-duplicate/HC-kang.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 contains-duplicate/HC-kang.ts diff --git a/contains-duplicate/HC-kang.ts b/contains-duplicate/HC-kang.ts new file mode 100644 index 000000000..b822e6225 --- /dev/null +++ b/contains-duplicate/HC-kang.ts @@ -0,0 +1,19 @@ +/** +217. Contains Duplicate + +Example 1: +Input: nums = [1,2,3,1] +Output: true + +Example 2: +Input: nums = [1,2,3,4] +Output: false + +Example 3: +Input: nums = [1,1,1,3,3,4,3,2,4,2] +Output: true + */ + +function containsDuplicate(nums: number[]): boolean { + return nums.length !== new Set(nums).size; +} From b300fb06547897d749280e39bb82aa9308df53e1 Mon Sep 17 00:00:00 2001 From: HC-kang Date: Mon, 12 Aug 2024 09:15:17 +0900 Subject: [PATCH 2/7] Feat: add solution for 191 --- number-of-1-bits/HC-kang.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 number-of-1-bits/HC-kang.ts diff --git a/number-of-1-bits/HC-kang.ts b/number-of-1-bits/HC-kang.ts new file mode 100644 index 000000000..fcb516f66 --- /dev/null +++ b/number-of-1-bits/HC-kang.ts @@ -0,0 +1,32 @@ +/** +191. Number of 1 Bits + +Example 1: +Input: n = 11 +Output: 3 +Explanation: +The input binary string 1011 has a total of three set bits. + +Example 2: +Input: n = 128 +Output: 1 +Explanation: +The input binary string 10000000 has a total of one set bit. + +Example 3: +Input: n = 2147483645 +Output: 30 +Explanation: +The input binary string 1111111111111111111111111111101 has a total of thirty set bits. + */ + +function hammingWeight(n: number): number { + return n.toString(2).split('1').length - 1; + + // let count = 0; + // while (n !== 0) { + // count += n & 1; + // n >>>= 1; + // } + // return count; +} From f1eee0e6115661c3fab432d824e9c8f5b0952685 Mon Sep 17 00:00:00 2001 From: HC-kang Date: Mon, 12 Aug 2024 21:57:01 +0900 Subject: [PATCH 3/7] Docs: add description for solved questions --- contains-duplicate/HC-kang.ts | 2 ++ number-of-1-bits/HC-kang.ts | 17 +++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/contains-duplicate/HC-kang.ts b/contains-duplicate/HC-kang.ts index b822e6225..3a74abde8 100644 --- a/contains-duplicate/HC-kang.ts +++ b/contains-duplicate/HC-kang.ts @@ -14,6 +14,8 @@ Input: nums = [1,1,1,3,3,4,3,2,4,2] Output: true */ +// Time complexity: O(n) +// Space complexity: O(n) function containsDuplicate(nums: number[]): boolean { return nums.length !== new Set(nums).size; } diff --git a/number-of-1-bits/HC-kang.ts b/number-of-1-bits/HC-kang.ts index fcb516f66..ab1ed5ddb 100644 --- a/number-of-1-bits/HC-kang.ts +++ b/number-of-1-bits/HC-kang.ts @@ -21,12 +21,17 @@ The input binary string 1111111111111111111111111111101 has a total of thirty se */ function hammingWeight(n: number): number { + // Time complexity: O(logn) + // Space complexity: O(logn) + // but it has a better readability return n.toString(2).split('1').length - 1; - // let count = 0; - // while (n !== 0) { - // count += n & 1; - // n >>>= 1; - // } - // return count; + // Time complexity: O(logn) + // Space complexity: O(1) + let count = 0; + while (n !== 0) { + count += n & 1; + n >>>= 1; + } + return count; } From 9517d44e6e913a340f1bfe98a15458f23623bc0f Mon Sep 17 00:00:00 2001 From: HC-kang Date: Tue, 13 Aug 2024 08:44:16 +0900 Subject: [PATCH 4/7] Feat: add solution for 347, 647 --- number-of-1-bits/HC-kang.ts | 3 +- palindromic-substrings/HC-kang.ts | 93 ++++++++++++++++++++++++++++++ top-k-frequent-elements/HC-kang.ts | 24 ++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 palindromic-substrings/HC-kang.ts create mode 100644 top-k-frequent-elements/HC-kang.ts diff --git a/number-of-1-bits/HC-kang.ts b/number-of-1-bits/HC-kang.ts index ab1ed5ddb..8eaba5aa1 100644 --- a/number-of-1-bits/HC-kang.ts +++ b/number-of-1-bits/HC-kang.ts @@ -23,11 +23,12 @@ The input binary string 1111111111111111111111111111101 has a total of thirty se function hammingWeight(n: number): number { // Time complexity: O(logn) // Space complexity: O(logn) - // but it has a better readability + // it has a better readability and not so bad in space complexity return n.toString(2).split('1').length - 1; // Time complexity: O(logn) // Space complexity: O(1) + // it's better in space complexity, but sometimes the bitwise operation is not easy to understand let count = 0; while (n !== 0) { count += n & 1; diff --git a/palindromic-substrings/HC-kang.ts b/palindromic-substrings/HC-kang.ts new file mode 100644 index 000000000..480c41a80 --- /dev/null +++ b/palindromic-substrings/HC-kang.ts @@ -0,0 +1,93 @@ +/* +647. Palindromic Substrings + +Example 1: +Input: s = "abc" +Output: 3 +Explanation: Three palindromic strings: "a", "b", "c". + +Example 2: +Input: s = "aaa" +Output: 6 +Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa". + */ + +// Time complexity: O(n^3) +// Space complexity: O(n^3) +function countSubstrings(s: string): number { + function isPalindrome(s: string): boolean { + if (s.length === 0) return false; + if (s.length === 1) return true; + let left = 0; + let right = s.length - 1; + while (left < right) { + if (s[left] !== s[right]) return false; + left++; + right--; + } + return true; + } + + const candidates = new Map(); + for (let i = 0; i < s.length; i++) { + for (let j = i + 1; j <= s.length; j++) { + // this will cost both t.c. and s.c. O(n^3) + candidates.set(s.slice(i, j), (candidates.get(s.slice(i, j)) || 0) + 1); + } + } + + let count = 0; + for (const [key, value] of candidates) { + if (isPalindrome(key)) count += value + } + + return count; +}; + +// Time complexity: O(n^3) +// Space complexity: O(1) +function countSubstrings(s: string): number { + function isPalindrome(s: string): boolean { + if (s.length === 0) return false; + if (s.length === 1) return true; + let left = 0; + let right = s.length - 1; + while (left < right) { + if (s[left] !== s[right]) return false; + left++; + right--; + } + return true; + } + + let count = 0; + for (let i = 0; i < s.length; i++) { + for (let j = i + 1; j <= s.length; j++) { + // this will cause t.c. O(n^3). need to optimize this part + if (isPalindrome(s.slice(i, j))) count++; + } + } + + return count; +} + +// Time complexity: O(n^2) +// Space complexity: O(1) +function countSubstrings(s: string): number { + function expandIsPalindrome(left: number, right: number): number { + let count = 0; + while (left >= 0 && right < s.length && s[left] === s[right]) { + count++; + left--; + right++; + } + return count; + } + + let count = 0; + for (let i = 0; i < s.length; i++) { + count += expandIsPalindrome(i, i); + count += expandIsPalindrome(i, i + 1); + } + return count; +} diff --git a/top-k-frequent-elements/HC-kang.ts b/top-k-frequent-elements/HC-kang.ts new file mode 100644 index 000000000..8c059b3ff --- /dev/null +++ b/top-k-frequent-elements/HC-kang.ts @@ -0,0 +1,24 @@ +/* +347. Top K Frequent Elements + +Example 1: +Input: nums = [1,1,1,2,2,3], k = 2 +Output: [1,2] + +Example 2: +Input: nums = [1], k = 1 +Output: [1] + */ + +// Time complexity: O(nlogn) +// Space complexity: O(n) +function topKFrequent(nums: number[], k: number): number[] { + const acc = new Map(); + for (const num of nums) { // s.c. O(n) + acc.set(num, (acc.get(num) || 0) + 1); + } + return Array.from(acc.entries()) + .sort((a, b) => b[1] - a[1]) // this will cost t.c. O(nlogn) + .slice(0, k) + .map((v) => v[0]); +} From 0cac7f60766a6c44b03e82a7538af7789cb628f2 Mon Sep 17 00:00:00 2001 From: HC-kang Date: Tue, 13 Aug 2024 08:59:23 +0900 Subject: [PATCH 5/7] Feat: add solution for 230 --- kth-smallest-element-in-a-bst/HC-kang.ts | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 kth-smallest-element-in-a-bst/HC-kang.ts diff --git a/kth-smallest-element-in-a-bst/HC-kang.ts b/kth-smallest-element-in-a-bst/HC-kang.ts new file mode 100644 index 000000000..61efb0d84 --- /dev/null +++ b/kth-smallest-element-in-a-bst/HC-kang.ts @@ -0,0 +1,50 @@ +/* +230. Kth Smallest Element in a BST + +Example 1: + 3 + / \ + 1 4 + \ + 2 +Input: root = [3,1,4,null,2], k = 1 +Output: 1 + +Example 2: + 5 + / \ + 3 6 + / \ + 2 4 + / + 1 +Input: root = [5,3,6,2,4,null,null,1], k = 3 +Output: 3 + */ + +// 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) +// } +// } + +// Time complexity: O(n) +// Space complexity: O(n) +function kthSmallest(root: TreeNode | null, k: number): number { + function inorder(root: TreeNode | null, arr: number[]) { + if (!root) return; + + inorder(root.left, arr); + arr.push(root.val); + inorder(root.right, arr); + } + + const arr: number[] = []; + inorder(root, arr); + return arr[k - 1]; +} From 5b4f4292349490d001273427bbf2106434a8f18f Mon Sep 17 00:00:00 2001 From: HC-kang Date: Tue, 13 Aug 2024 09:06:03 +0900 Subject: [PATCH 6/7] Feat: add an awesome code from leetcode --- kth-smallest-element-in-a-bst/HC-kang.ts | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/kth-smallest-element-in-a-bst/HC-kang.ts b/kth-smallest-element-in-a-bst/HC-kang.ts index 61efb0d84..4d8b7c4dd 100644 --- a/kth-smallest-element-in-a-bst/HC-kang.ts +++ b/kth-smallest-element-in-a-bst/HC-kang.ts @@ -48,3 +48,60 @@ function kthSmallest(root: TreeNode | null, k: number): number { inorder(root, arr); return arr[k - 1]; } + +/** + * Awesome solution from leetcode + */ +function kthSmallest(root: TreeNode | null, k: number): number { + /* + define. return the kth smallest value in a BST. + assess. smallest value can be 0. At least k nodes, which can be at its smallest, 1. + approach. DFS with backtracking. Traverse down the left edges until we hit null. if k is 1, return that value. Else, backtrack, go right, then try to go left again. Use a stack. + */ + + // let currentRank = 0; + + // let stack = []; + + // let currentNode = root; + + // while (currentNode || stack.length > 0) { + // while (currentNode) { + // stack.push(currentNode); + + // currentNode = currentNode.left; + // } + + // currentNode = stack.pop(); + + // currentRank++; + + // if (currentRank === k) return currentNode.val; + + // currentNode = currentNode.right; + // } + + const stack = []; + + let currentRank = 0; + + let currentNode = root; + + while (currentNode || stack.length > 0) { + + while (currentNode) { + stack.push(currentNode); + + currentNode = currentNode.left; + } + + currentNode = stack.pop(); + + currentRank++; + + if (currentRank === k) return currentNode.val; + + currentNode = currentNode.right; + } + +}; From 535930e59238e88672b1500ad8102908148a7fa0 Mon Sep 17 00:00:00 2001 From: HC-kang Date: Tue, 13 Aug 2024 20:38:31 +0900 Subject: [PATCH 7/7] Refactor: apply code review feedback --- kth-smallest-element-in-a-bst/HC-kang.ts | 24 +----------------------- top-k-frequent-elements/HC-kang.ts | 6 +++--- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/kth-smallest-element-in-a-bst/HC-kang.ts b/kth-smallest-element-in-a-bst/HC-kang.ts index 4d8b7c4dd..77d6ad15f 100644 --- a/kth-smallest-element-in-a-bst/HC-kang.ts +++ b/kth-smallest-element-in-a-bst/HC-kang.ts @@ -50,6 +50,7 @@ function kthSmallest(root: TreeNode | null, k: number): number { } /** + * NOT MY SOLUTION - NO NEED TO REVIEW * Awesome solution from leetcode */ function kthSmallest(root: TreeNode | null, k: number): number { @@ -58,29 +59,6 @@ function kthSmallest(root: TreeNode | null, k: number): number { assess. smallest value can be 0. At least k nodes, which can be at its smallest, 1. approach. DFS with backtracking. Traverse down the left edges until we hit null. if k is 1, return that value. Else, backtrack, go right, then try to go left again. Use a stack. */ - - // let currentRank = 0; - - // let stack = []; - - // let currentNode = root; - - // while (currentNode || stack.length > 0) { - // while (currentNode) { - // stack.push(currentNode); - - // currentNode = currentNode.left; - // } - - // currentNode = stack.pop(); - - // currentRank++; - - // if (currentRank === k) return currentNode.val; - - // currentNode = currentNode.right; - // } - const stack = []; let currentRank = 0; diff --git a/top-k-frequent-elements/HC-kang.ts b/top-k-frequent-elements/HC-kang.ts index 8c059b3ff..32c9ec73a 100644 --- a/top-k-frequent-elements/HC-kang.ts +++ b/top-k-frequent-elements/HC-kang.ts @@ -13,11 +13,11 @@ Output: [1] // Time complexity: O(nlogn) // Space complexity: O(n) function topKFrequent(nums: number[], k: number): number[] { - const acc = new Map(); + const frequentMap = new Map(); for (const num of nums) { // s.c. O(n) - acc.set(num, (acc.get(num) || 0) + 1); + frequentMap.set(num, (frequentMap.get(num) || 0) + 1); } - return Array.from(acc.entries()) + return Array.from(frequentMap.entries()) .sort((a, b) => b[1] - a[1]) // this will cost t.c. O(nlogn) .slice(0, k) .map((v) => v[0]);