diff --git a/contains-duplicate/HC-kang.ts b/contains-duplicate/HC-kang.ts new file mode 100644 index 000000000..3a74abde8 --- /dev/null +++ b/contains-duplicate/HC-kang.ts @@ -0,0 +1,21 @@ +/** +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 + */ + +// Time complexity: O(n) +// Space complexity: O(n) +function containsDuplicate(nums: number[]): boolean { + return nums.length !== new Set(nums).size; +} 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..77d6ad15f --- /dev/null +++ b/kth-smallest-element-in-a-bst/HC-kang.ts @@ -0,0 +1,85 @@ +/* +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]; +} + +/** + * NOT MY SOLUTION - NO NEED TO REVIEW + * 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. + */ + 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; + } + +}; diff --git a/number-of-1-bits/HC-kang.ts b/number-of-1-bits/HC-kang.ts new file mode 100644 index 000000000..8eaba5aa1 --- /dev/null +++ b/number-of-1-bits/HC-kang.ts @@ -0,0 +1,38 @@ +/** +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 { + // Time complexity: O(logn) + // Space complexity: O(logn) + // 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; + n >>>= 1; + } + return count; +} 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..32c9ec73a --- /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 frequentMap = new Map(); + for (const num of nums) { // s.c. O(n) + frequentMap.set(num, (frequentMap.get(num) || 0) + 1); + } + 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]); +}