diff --git a/invert-binary-tree/Leo.py b/invert-binary-tree/Leo.py
new file mode 100644
index 000000000..e6c2aafde
--- /dev/null
+++ b/invert-binary-tree/Leo.py
@@ -0,0 +1,17 @@
+# 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:
+    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
+        if not root:
+            return None
+
+        else:
+            root.right, root.left = self.invertTree(root.left), self.invertTree(root.right)
+
+        return root
+
+        ## TC: O(n), SC: O(n), avg O(logn) if the given tree is balanced
diff --git a/linked-list-cycle/Leo.py b/linked-list-cycle/Leo.py
new file mode 100644
index 000000000..417667dc4
--- /dev/null
+++ b/linked-list-cycle/Leo.py
@@ -0,0 +1,31 @@
+# Definition for singly-linked list.
+# class ListNode:
+#     def __init__(self, x):
+#         self.val = x
+#         self.next = None
+
+class Solution:
+    def hasCycle(self, head: Optional[ListNode]) -> bool:
+        slow = head
+        fast = head
+
+        while fast and fast.next:
+            slow = slow.next
+            fast = fast.next.next
+            if slow == fast:
+                return True
+
+        return False
+
+        # visited = head
+
+        # while visited:
+        #     if visited.val == None:
+        #         return True
+
+        #     visited.val = None
+        #     visited = visited.next
+
+        # return False
+
+        # Both TC:O(n) and SC:O(1), but below one is kinda tricky solution
diff --git a/merge-two-sorted-lists/Leo.py b/merge-two-sorted-lists/Leo.py
new file mode 100644
index 000000000..1bdfca1a4
--- /dev/null
+++ b/merge-two-sorted-lists/Leo.py
@@ -0,0 +1,20 @@
+# Definition for singly-linked list.
+# class ListNode:
+#     def __init__(self, val=0, next=None):
+#         self.val = val
+#         self.next = next
+class Solution:
+    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
+        if not list1 or not list2:
+            return list1 or list2
+
+        if list1.val <= list2.val:
+            list1.next = self.mergeTwoLists(list1.next, list2)
+            return list1
+
+        else:
+            list2.next = self.mergeTwoLists(list1, list2.next)
+            return list2
+
+        ## TC: O(n) or O(n+m), depends on the length of list1 and list2
+        ## SC: O(max(m,n))
diff --git a/reverse-linked-list/Leo.py b/reverse-linked-list/Leo.py
new file mode 100644
index 000000000..7a5b284b2
--- /dev/null
+++ b/reverse-linked-list/Leo.py
@@ -0,0 +1,18 @@
+# Definition for singly-linked list.
+# class ListNode:
+#     def __init__(self, val=0, next=None):
+#         self.val = val
+#         self.next = next
+class Solution:
+    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
+        prev, curr = None, head
+
+        while curr:
+            tmp = curr.next ## save next node
+            curr.next = prev ## reverse next pointer to the prev
+            prev = curr ## update prev pointer with curr, since it's reversed now
+            curr = tmp ## move on to the next saved node
+
+        return prev
+
+        ## TC: O(n) SC: O(1)
diff --git a/valid-parentheses/Leo.py b/valid-parentheses/Leo.py
new file mode 100644
index 000000000..113d6fe5f
--- /dev/null
+++ b/valid-parentheses/Leo.py
@@ -0,0 +1,16 @@
+class Solution:
+    def isValid(self, s: str) -> bool:
+
+        d = {'(': ')', '[': ']', '{': '}'}
+        stack = []
+
+        for i in s:
+            if i in d:
+                stack.append(i)
+            elif len(stack) == 0 or d[stack.pop()] != i:
+                return False
+
+        return len(stack) == 0
+
+        ## O(n) time complexity but not that much fast by leetcode system...
+        ## Space complexity is also O(n)