From d05c6952aff9a5c27477625d358626a144a3dcc7 Mon Sep 17 00:00:00 2001
From: coloryourlife <95chris0319@gmail.com>
Date: Sat, 24 Aug 2024 00:37:02 -0700
Subject: [PATCH] coloryourlife: week2 solutions

---
 .../coloryourlife.py                          | 23 +++++++++++++++++
 counting-bits/coloryourlife.py                | 15 +++++++++++
 decode-ways/coloryourlife.py                  | 23 +++++++++++++++++
 encode-and-decode-strings/coloryourlife.py    | 25 +++++++++++++++++++
 valid-anagram/coloryourlife.py                | 18 +++++++++++++
 5 files changed, 104 insertions(+)
 create mode 100644 construct-binary-tree-from-preorder-and-inorder-traversal/coloryourlife.py
 create mode 100644 counting-bits/coloryourlife.py
 create mode 100644 decode-ways/coloryourlife.py
 create mode 100644 encode-and-decode-strings/coloryourlife.py
 create mode 100644 valid-anagram/coloryourlife.py

diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal/coloryourlife.py b/construct-binary-tree-from-preorder-and-inorder-traversal/coloryourlife.py
new file mode 100644
index 000000000..bc8e40952
--- /dev/null
+++ b/construct-binary-tree-from-preorder-and-inorder-traversal/coloryourlife.py
@@ -0,0 +1,23 @@
+# Definition for a binary tree node.
+# class TreeNode:
+#     def __init__(self, val=0, left=None, right=None):
+#         self.val = val
+#         self.left = left
+#         self.right = right
+class Solution:
+    # T: O(N)
+    # S: O(N)
+    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
+        # preorder : root - left - right
+        # inorder : left - root - right
+        if not preorder and not inorder:
+            return None
+        
+        root = TreeNode(preorder[0])
+        mid = inorder.index(preorder[0])
+        
+        root.left = self.buildTree(preorder[1 : mid + 1], inorder[:mid])
+        root.right = self.buildTree(preorder[mid + 1 :], inorder[mid+1:])
+        
+        return root
+
diff --git a/counting-bits/coloryourlife.py b/counting-bits/coloryourlife.py
new file mode 100644
index 000000000..6969b732c
--- /dev/null
+++ b/counting-bits/coloryourlife.py
@@ -0,0 +1,15 @@
+# T: O(N)
+# S: O(N)
+class Solution:
+    def countBits(self, n: int) -> List[int]:
+        res = []
+        for i in range(n + 1):
+            m = i
+            cnt = 0
+            while m > 0:
+                if m & 1 == 1:
+                    cnt += 1
+                m = m >> 1
+            res.append(cnt)
+        return res
+
diff --git a/decode-ways/coloryourlife.py b/decode-ways/coloryourlife.py
new file mode 100644
index 000000000..b303fbfb5
--- /dev/null
+++ b/decode-ways/coloryourlife.py
@@ -0,0 +1,23 @@
+class Solution:
+    # T: O(N)
+    # S: O(N)
+    def numDecodings(self, s: str) -> int:
+        # The subproblem would be any portion of string 
+        dp = {len(s): 1}
+
+        def dfs(i):
+            if i in dp:
+                return dp[i]
+            if s[i] == "0":
+                return 0
+
+            res = dfs(i + 1)
+            if i + 1 < len(s) and (
+                s[i] == "1" or s[i] == "2" and s[i + 1] in "0123456"
+            ):
+                res += dfs(i + 2)
+            dp[i] = res
+            return res
+
+        return dfs(0)
+
diff --git a/encode-and-decode-strings/coloryourlife.py b/encode-and-decode-strings/coloryourlife.py
new file mode 100644
index 000000000..3f454fc56
--- /dev/null
+++ b/encode-and-decode-strings/coloryourlife.py
@@ -0,0 +1,25 @@
+class Codec:
+    # T: O(n)
+    # S: O(1)
+    def encode(self, strs: List[str]) -> str:
+        """Encodes a list of strings to a single string.
+        """
+        res = ""
+        for s in strs:
+            res += str(len(s)) + "#" + s
+        return res
+ 
+
+    def decode(self, s: str) -> List[str]:
+        """Decodes a single string to a list of strings.
+        """
+        res, i = [], 0
+        while i < len(s):
+            j = i
+            while s[j] != "#":
+                j += 1
+            length = int(s[i:j])
+            res.append(s[j + 1 : j + 1 + length])
+            i = j + 1 + length
+        return res
+
diff --git a/valid-anagram/coloryourlife.py b/valid-anagram/coloryourlife.py
new file mode 100644
index 000000000..c6e4c6c4a
--- /dev/null
+++ b/valid-anagram/coloryourlife.py
@@ -0,0 +1,18 @@
+class Solution:
+    def isAnagram(self, s: str, t: str) -> bool:
+        # 1. sorting and compare : O(nlogn)
+        # 2. hashing: O(n)
+        # 3. array: O(n)
+        if len(s) != len(t):
+            return False
+        char_dict = defaultdict(int)
+        for c in s:
+            char_dict[c] += 1
+        
+        for c in t:
+            char_dict[c] -= 1
+            if char_dict[c] < 0:
+                return False
+        
+        return True
+