diff --git a/container-with-most-water/HC-kang.ts b/container-with-most-water/HC-kang.ts
new file mode 100644
index 000000000..82666cfa2
--- /dev/null
+++ b/container-with-most-water/HC-kang.ts
@@ -0,0 +1,21 @@
+/**
+ * https://leetcode.com/problems/container-with-most-water/
+ * T.C. O(n)
+ * S.C. O(1)
+ */
+function maxArea(height: number[]): number {
+  let [res, i, j] = [0, 0, height.length - 1];
+
+  while (i < j) {
+    const volume = Math.min(height[i], height[j]) * (j - i);
+    res = Math.max(res, volume);
+
+    if (height[i] < height[j]) {
+      i++;
+    } else {
+      j--;
+    }
+  }
+
+  return res;
+}
diff --git a/design-add-and-search-words-data-structure/HC-kang.ts b/design-add-and-search-words-data-structure/HC-kang.ts
new file mode 100644
index 000000000..efa102152
--- /dev/null
+++ b/design-add-and-search-words-data-structure/HC-kang.ts
@@ -0,0 +1,102 @@
+/**
+ * https://leetcode.com/problems/design-add-and-search-words-data-structure
+ */
+// Using Trie
+class WordDictionary {
+  constructor(private root: Record<string, any> = {}) {}
+
+  /**
+   * T.C. O(L) L: length of a word
+   * S.C. O(L)
+   */
+  addWord(word: string): void {
+    let node = this.root;
+    for (const char of word) {
+      if (!node[char]) {
+        node[char] = {};
+      }
+      node = node[char];
+    }
+    node['isEnd'] = true;
+  }
+
+  /**
+   * T.C. O(N) - there are only 2 dots in the word(26 * 26 * N)
+   * S.C. O(N * L) N: number of words, L: length of a word
+   */
+  search(word: string): boolean {
+    return this.dfs(word, this.root);
+  }
+
+  private dfs(word: string, node: Record<string, any>): boolean {
+    for (let i = 0; i < word.length; i++) {
+      if (word[i] === '.') {
+        for (const key in node) {
+          if (this.dfs(word.slice(i + 1), node[key])) {
+            return true;
+          }
+        }
+        return false;
+      }
+      if (!node[word[i]]) {
+        return false;
+      }
+      node = node[word[i]];
+    }
+    return !!node['isEnd'];
+  }
+}
+
+// Using Array and Set
+class WordDictionary {
+  constructor(
+    private words: Set<string>[] = Array.from({ length: 25 }, () => new Set())
+  ) {}
+
+  /**
+   * T.C. O(1)
+   * S.C. O(N * L)
+   */
+  addWord(word: string): void {
+    this.words[word.length - 1].add(word);
+  }
+
+  /**
+   * T.C. O(N * L) N: number of words, L: length of a word
+   * S.C. O(1)
+   */
+  search(word: string): boolean {
+    const hasDot = word.indexOf('.') !== -1;
+    const set = this.words[word.length - 1];
+
+    if (!hasDot) {
+      return set.has(word);
+    }
+
+    for (const w of set) {
+      let i = 0;
+      while (i < word.length) {
+        if (word[i] == '.') {
+          i++;
+          continue;
+        }
+        if (word[i] !== w[i]) {
+          break;
+        }
+        i++;
+      }
+
+      if (i === word.length) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * Your WordDictionary object will be instantiated and called as such:
+ * var obj = new WordDictionary()
+ * obj.addWord(word)
+ * var param_2 = obj.search(word)
+ */
diff --git a/longest-increasing-subsequence/HC-kang.ts b/longest-increasing-subsequence/HC-kang.ts
new file mode 100644
index 000000000..0d4e5e284
--- /dev/null
+++ b/longest-increasing-subsequence/HC-kang.ts
@@ -0,0 +1,32 @@
+/**
+ * https://leetcode.com/problems/longest-increasing-subsequence
+ * T.C. O(nlogn)
+ * S.C. O(n)
+ */
+function lengthOfLIS(nums: number[]): number {
+  const sub: number[] = [];
+
+  function findSlot(num: number): number {
+    let left = 0;
+    let right = sub.length - 1;
+
+    while (left <= right) {
+      const mid = Math.floor((left + right) / 2);
+      if (sub[mid] < num) {
+        left = mid + 1;
+      } else {
+        right = mid - 1;
+      }
+    }
+
+    return left;
+  }
+
+  for (let i = 0; i < nums.length; i++) {
+    const num = nums[i];
+    const slot = findSlot(num);
+    sub[slot] = num;
+  }
+
+  return sub.length;
+}
diff --git a/spiral-matrix/HC-kang.ts b/spiral-matrix/HC-kang.ts
new file mode 100644
index 000000000..f2d1616e2
--- /dev/null
+++ b/spiral-matrix/HC-kang.ts
@@ -0,0 +1,44 @@
+/**
+ * https://leetcode.com/problems/spiral-matrix
+ * T.C. O(m * n)
+ * S.C. O(m * n)
+ */
+function spiralOrder(matrix: number[][]): number[] {
+  const clockwise = [
+    [0, 1],
+    [1, 0],
+    [0, -1],
+    [-1, 0],
+  ];
+  let currentDirection = 0;
+
+  const visited = new Array(matrix.length)
+    .fill(0)
+    .map(() => new Array(matrix[0].length).fill(false));
+
+  const result: number[] = [];
+
+  let row = 0;
+  let col = 0;
+
+  while (result.length < matrix.length * matrix[0].length) {
+    result.push(matrix[row][col]);
+    visited[row][col] = true;
+
+    const nextRow = row + clockwise[currentDirection][0];
+    const nextCol = col + clockwise[currentDirection][1];
+
+    if (
+      nextRow < 0 || nextRow >= matrix.length ||
+      nextCol < 0 || nextCol >= matrix[0].length ||
+      visited[nextRow][nextCol]
+    ) {
+      currentDirection = (currentDirection + 1) % 4;
+    }
+
+    row += clockwise[currentDirection][0];
+    col += clockwise[currentDirection][1];
+  }
+
+  return result;
+}
diff --git a/valid-parentheses/HC-kang.ts b/valid-parentheses/HC-kang.ts
new file mode 100644
index 000000000..57037196b
--- /dev/null
+++ b/valid-parentheses/HC-kang.ts
@@ -0,0 +1,17 @@
+/**
+ * https://leetcode.com/problems/valid-parentheses
+ * T.C. O(n)
+ * S.C. O(n)
+ */
+function isValid(s: string): boolean {
+  const pairs: Record<string, string> = { '{': '}', '[': ']', '(': ')' };
+  const stack: string[] = [];
+
+  if (s.length % 2 == 1) return false;
+
+  for (const char of s) {
+    if (pairs[char]) stack.push(char);
+    else if (char != pairs[stack.pop()!]) return false;
+  }
+  return !stack.length;
+}