diff --git a/g0101_0200/s0105_construct_binary_tree_from_preorder_and_inorder_traversal/readme.md b/g0101_0200/s0105_construct_binary_tree_from_preorder_and_inorder_traversal/readme.md
new file mode 100644
index 0000000..5ed1301
--- /dev/null
+++ b/g0101_0200/s0105_construct_binary_tree_from_preorder_and_inorder_traversal/readme.md
@@ -0,0 +1,83 @@
+105\. Construct Binary Tree from Preorder and Inorder Traversal
+
+Medium
+
+Given two integer arrays `preorder` and `inorder` where `preorder` is the preorder traversal of a binary tree and `inorder` is the inorder traversal of the same tree, construct and return _the binary tree_.
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2021/02/19/tree.jpg)
+
+**Input:** preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
+
+**Output:** [3,9,20,null,null,15,7] 
+
+**Example 2:**
+
+**Input:** preorder = [-1], inorder = [-1]
+
+**Output:** [-1] 
+
+**Constraints:**
+
+*   `1 <= preorder.length <= 3000`
+*   `inorder.length == preorder.length`
+*   `-3000 <= preorder[i], inorder[i] <= 3000`
+*   `preorder` and `inorder` consist of **unique** values.
+*   Each value of `inorder` also appears in `preorder`.
+*   `preorder` is **guaranteed** to be the preorder traversal of the tree.
+*   `inorder` is **guaranteed** to be the inorder traversal of the tree.
+
+To solve this task, we can use a recursive approach to construct the binary tree. We'll define a `Solution` class with a method `buildTree` to perform this task. Here are the steps:
+
+1. Define the `Solution` class.
+2. Define the `buildTree` method which takes `preorder` and `inorder` lists as input.
+3. Create a helper function, let's call it `buildTreeHelper`, that takes the indices representing the current subtree in preorder and inorder lists.
+4. In the `buildTreeHelper` function, if the `preorder` list is empty or the `inorder` list is empty, return `None`, indicating an empty subtree.
+5. Otherwise, the first element of the `preorder` list would be the root of the current subtree. Create a node for this root.
+6. Find the index of the root value in the `inorder` list. This index will partition the `inorder` list into left and right subtrees.
+7. Recursively call `buildTreeHelper` for the left subtree with appropriate indices.
+8. Recursively call `buildTreeHelper` for the right subtree with appropriate indices.
+9. Return the root node.
+10. Call `buildTreeHelper` from the `buildTree` method with initial indices for the entire preorder and inorder lists.
+11. Return the root node obtained from `buildTreeHelper`.
+
+Here's the Python code implementing these steps:
+
+```python
+class TreeNode:
+    def __init__(self, val=0, left=None, right=None):
+        self.val = val
+        self.left = left
+        self.right = right
+
+class Solution:
+    def buildTree(self, preorder, inorder):
+        if not preorder or not inorder:
+            return None
+        
+        def buildTreeHelper(pre_start, pre_end, in_start, in_end):
+            if pre_start > pre_end or in_start > in_end:
+                return None
+            
+            root_val = preorder[pre_start]
+            root = TreeNode(root_val)
+            
+            # Find index of root value in inorder list
+            root_index = inorder.index(root_val)
+            
+            # Calculate the number of nodes in the left subtree
+            left_subtree_size = root_index - in_start
+            
+            # Recursively build left subtree
+            root.left = buildTreeHelper(pre_start + 1, pre_start + left_subtree_size, in_start, root_index - 1)
+            
+            # Recursively build right subtree
+            root.right = buildTreeHelper(pre_start + left_subtree_size + 1, pre_end, root_index + 1, in_end)
+            
+            return root
+        
+        return buildTreeHelper(0, len(preorder) - 1, 0, len(inorder) - 1)
+```
+
+You can then use this `Solution` class to construct the binary tree from preorder and inorder traversal arrays.
\ No newline at end of file
diff --git a/g0101_0200/s0114_flatten_binary_tree_to_linked_list/readme.md b/g0101_0200/s0114_flatten_binary_tree_to_linked_list/readme.md
new file mode 100644
index 0000000..774e2d9
--- /dev/null
+++ b/g0101_0200/s0114_flatten_binary_tree_to_linked_list/readme.md
@@ -0,0 +1,80 @@
+114\. Flatten Binary Tree to Linked List
+
+Medium
+
+Given the `root` of a binary tree, flatten the tree into a "linked list":
+
+*   The "linked list" should use the same `TreeNode` class where the `right` child pointer points to the next node in the list and the `left` child pointer is always `null`.
+*   The "linked list" should be in the same order as a [**pre-order** **traversal**](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR) of the binary tree.
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2021/01/14/flaten.jpg)
+
+**Input:** root = [1,2,5,3,4,null,6]
+
+**Output:** [1,null,2,null,3,null,4,null,5,null,6] 
+
+**Example 2:**
+
+**Input:** root = []
+
+**Output:** [] 
+
+**Example 3:**
+
+**Input:** root = [0]
+
+**Output:** [0] 
+
+**Constraints:**
+
+*   The number of nodes in the tree is in the range `[0, 2000]`.
+*   `-100 <= Node.val <= 100`
+
+**Follow up:** Can you flatten the tree in-place (with `O(1)` extra space)?
+
+To solve this task, we can use a recursive approach to flatten the binary tree. We'll define a `Solution` class with a method `flatten` to perform this task. Here are the steps:
+
+1. Define the `Solution` class.
+2. Define the `flatten` method which takes `root` as input.
+3. Create a helper function, let's call it `flattenHelper`, that takes a node as input.
+4. In the `flattenHelper` function, if the current node is `None`, return `None`.
+5. Otherwise, recursively flatten the left subtree and right subtree.
+6. Once both subtrees are flattened, set the `right` child of the root to the flattened left subtree.
+7. Traverse to the end of the flattened left subtree and attach the flattened right subtree to its `right`.
+8. Set the `left` child of the root to `None`.
+9. Return the last node of the flattened tree (either the last node of the flattened right subtree or the last node of the flattened left subtree if the right subtree is `None`).
+10. Call `flattenHelper` from the `flatten` method with the root node.
+11. Return the root node.
+
+Here's the Python code implementing these steps:
+
+```python
+class TreeNode:
+    def __init__(self, val=0, left=None, right=None):
+        self.val = val
+        self.left = left
+        self.right = right
+
+class Solution:
+    def flatten(self, root):
+        def flattenHelper(node):
+            if not node:
+                return None
+            
+            left_last = flattenHelper(node.left)
+            right_last = flattenHelper(node.right)
+            
+            if left_last:
+                left_last.right = node.right
+                node.right = node.left
+                node.left = None
+            
+            return right_last if right_last else left_last if left_last else node
+        
+        flattenHelper(root)
+        return root
+```
+
+You can then use this `Solution` class to flatten the binary tree into a linked list in pre-order traversal order.
\ No newline at end of file
diff --git a/g0101_0200/s0121_best_time_to_buy_and_sell_stock/readme.md b/g0101_0200/s0121_best_time_to_buy_and_sell_stock/readme.md
new file mode 100644
index 0000000..1dcbfec
--- /dev/null
+++ b/g0101_0200/s0121_best_time_to_buy_and_sell_stock/readme.md
@@ -0,0 +1,60 @@
+121\. Best Time to Buy and Sell Stock
+
+Easy
+
+You are given an array `prices` where `prices[i]` is the price of a given stock on the `ith` day.
+
+You want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock.
+
+Return _the maximum profit you can achieve from this transaction_. If you cannot achieve any profit, return `0`.
+
+**Example 1:**
+
+**Input:** prices = [7,1,5,3,6,4]
+
+**Output:** 5
+
+**Explanation:** Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell. 
+
+**Example 2:**
+
+**Input:** prices = [7,6,4,3,1]
+
+**Output:** 0
+
+**Explanation:** In this case, no transactions are done and the max profit = 0. 
+
+**Constraints:**
+
+*   <code>1 <= prices.length <= 10<sup>5</sup></code>
+*   <code>0 <= prices[i] <= 10<sup>4</sup></code>
+
+To solve this task, we can use a greedy approach. We'll iterate through the prices array and keep track of the minimum price seen so far and the maximum profit we can achieve. Here are the steps:
+
+1. Define the `Solution` class.
+2. Define the `maxProfit` method which takes `prices` as input.
+3. Initialize variables `min_price` to store the minimum price seen so far and `max_profit` to store the maximum profit.
+4. Iterate through the `prices` array.
+5. Update `min_price` to the minimum of the current price and `min_price`.
+6. Update `max_profit` to the maximum of the difference between the current price and `min_price`, and `max_profit`.
+7. After iterating through the array, return `max_profit`.
+
+Here's the Python code implementing these steps:
+
+```python
+class Solution:
+    def maxProfit(self, prices):
+        if not prices or len(prices) == 1:
+            return 0
+        
+        min_price = prices[0]
+        max_profit = 0
+        
+        for price in prices[1:]:
+            min_price = min(min_price, price)
+            max_profit = max(max_profit, price - min_price)
+        
+        return max_profit
+```
+
+You can then use this `Solution` class to find the maximum profit you can achieve by buying and selling stocks.
\ No newline at end of file
diff --git a/g0101_0200/s0124_binary_tree_maximum_path_sum/readme.md b/g0101_0200/s0124_binary_tree_maximum_path_sum/readme.md
new file mode 100644
index 0000000..943ab76
--- /dev/null
+++ b/g0101_0200/s0124_binary_tree_maximum_path_sum/readme.md
@@ -0,0 +1,79 @@
+124\. Binary Tree Maximum Path Sum
+
+Hard
+
+A **path** in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence **at most once**. Note that the path does not need to pass through the root.
+
+The **path sum** of a path is the sum of the node's values in the path.
+
+Given the `root` of a binary tree, return _the maximum **path sum** of any **non-empty** path_.
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2020/10/13/exx1.jpg)
+
+**Input:** root = [1,2,3]
+
+**Output:** 6
+
+**Explanation:** The optimal path is 2 -> 1 -> 3 with a path sum of 2 + 1 + 3 = 6. 
+
+**Example 2:**
+
+![](https://assets.leetcode.com/uploads/2020/10/13/exx2.jpg)
+
+**Input:** root = [-10,9,20,null,null,15,7]
+
+**Output:** 42
+
+**Explanation:** The optimal path is 15 -> 20 -> 7 with a path sum of 15 + 20 + 7 = 42. 
+
+**Constraints:**
+
+*   The number of nodes in the tree is in the range <code>[1, 3 * 10<sup>4</sup>]</code>.
+*   `-1000 <= Node.val <= 1000`
+
+To solve this task, we can use a recursive approach to traverse the binary tree and calculate the maximum path sum. We'll define a `Solution` class with a method `maxPathSum` to perform this task. Here are the steps:
+
+1. Define the `Solution` class.
+2. Define the `maxPathSum` method which takes `root` as input.
+3. Create a helper function, let's call it `maxPathSumHelper`, that takes a node as input.
+4. In the `maxPathSumHelper` function, if the current node is `None`, return `0`.
+5. Recursively calculate the maximum path sum for the left and right subtrees using `maxPathSumHelper`.
+6. Calculate the maximum path sum passing through the current node, considering the possibility of including both left and right subtrees.
+7. Update a global variable `max_sum` to keep track of the maximum path sum encountered so far.
+8. Return the maximum path sum that includes either the current node or just one of its subtrees (if the sum with both subtrees is negative).
+9. Call `maxPathSumHelper` from the `maxPathSum` method with the root node.
+10. Return the global variable `max_sum`.
+
+Here's the Python code implementing these steps:
+
+```python
+class TreeNode:
+    def __init__(self, val=0, left=None, right=None):
+        self.val = val
+        self.left = left
+        self.right = right
+
+class Solution:
+    def maxPathSum(self, root):
+        def maxPathSumHelper(node):
+            if not node:
+                return 0
+            
+            left_sum = max(maxPathSumHelper(node.left), 0)
+            right_sum = max(maxPathSumHelper(node.right), 0)
+            
+            current_max = node.val + left_sum + right_sum
+            
+            global max_sum
+            max_sum = max(max_sum, current_max)
+            
+            return node.val + max(left_sum, right_sum)
+        
+        max_sum = float('-inf')
+        maxPathSumHelper(root)
+        return max_sum
+```
+
+You can then use this `Solution` class to find the maximum path sum of any non-empty path in the binary tree.
\ No newline at end of file
diff --git a/g0101_0200/s0128_longest_consecutive_sequence/readme.md b/g0101_0200/s0128_longest_consecutive_sequence/readme.md
new file mode 100644
index 0000000..dc5aca1
--- /dev/null
+++ b/g0101_0200/s0128_longest_consecutive_sequence/readme.md
@@ -0,0 +1,62 @@
+128\. Longest Consecutive Sequence
+
+Medium
+
+Given an unsorted array of integers `nums`, return _the length of the longest consecutive elements sequence._
+
+You must write an algorithm that runs in `O(n)` time.
+
+**Example 1:**
+
+**Input:** nums = [100,4,200,1,3,2]
+
+**Output:** 4
+
+**Explanation:** The longest consecutive elements sequence is `[1, 2, 3, 4]`. Therefore its length is 4. 
+
+**Example 2:**
+
+**Input:** nums = [0,3,7,2,5,8,4,6,0,1]
+
+**Output:** 9 
+
+**Constraints:**
+
+*   <code>0 <= nums.length <= 10<sup>5</sup></code>
+*   <code>-10<sup>9</sup> <= nums[i] <= 10<sup>9</sup></code>
+
+To solve this task efficiently in O(n) time, we can use a HashSet to store all the elements of the array. Then, we can iterate through the array and for each element, check if the previous consecutive element (element - 1) exists in the set. If it does not exist, it means that the current element is the start of a new consecutive sequence. We can then keep track of the length of the consecutive sequence starting from the current element by continuously incrementing the current element until it no longer exists in the set. At each step, we update the maximum length of consecutive elements encountered so far. Here are the steps:
+
+1. Define the `Solution` class.
+2. Define the `longestConsecutive` method which takes `nums` as input.
+3. Create a set `num_set` to store all elements of the array.
+4. Initialize a variable `max_length` to store the maximum length of consecutive sequence encountered so far.
+5. Iterate through the elements of the array.
+6. For each element `num`, check if `num - 1` exists in `num_set`. If it does not exist, it means that `num` is the start of a new consecutive sequence.
+7. Increment `current_length` by 1 and continuously increment `num` until it no longer exists in `num_set`.
+8. Update `max_length` with the maximum of `max_length` and `current_length`.
+9. After iterating through all elements, return `max_length`.
+
+Here's the Python code implementing these steps:
+
+```python
+class Solution:
+    def longestConsecutive(self, nums):
+        num_set = set(nums)
+        max_length = 0
+        
+        for num in nums:
+            if num - 1 not in num_set:
+                current_num = num
+                current_length = 1
+                
+                while current_num + 1 in num_set:
+                    current_num += 1
+                    current_length += 1
+                
+                max_length = max(max_length, current_length)
+        
+        return max_length
+```
+
+You can then use this `Solution` class to find the length of the longest consecutive elements sequence in the given unsorted array.
\ No newline at end of file
diff --git a/g0101_0200/s0131_palindrome_partitioning/readme.md b/g0101_0200/s0131_palindrome_partitioning/readme.md
new file mode 100644
index 0000000..d54264d
--- /dev/null
+++ b/g0101_0200/s0131_palindrome_partitioning/readme.md
@@ -0,0 +1,64 @@
+131\. Palindrome Partitioning
+
+Medium
+
+Given a string `s`, partition `s` such that every substring of the partition is a **palindrome**. Return all possible palindrome partitioning of `s`.
+
+A **palindrome** string is a string that reads the same backward as forward.
+
+**Example 1:**
+
+**Input:** s = "aab"
+
+**Output:** [["a","a","b"],["aa","b"]] 
+
+**Example 2:**
+
+**Input:** s = "a"
+
+**Output:** [["a"]] 
+
+**Constraints:**
+
+*   `1 <= s.length <= 16`
+*   `s` contains only lowercase English letters.
+
+To solve this task, we can use a backtracking approach. Here are the steps to solve the problem using the `Solution` class:
+
+1. Define the `Solution` class with a method `partition` that takes a string `s` as input and returns a list of lists containing all possible palindrome partitions of `s`.
+2. Within the `partition` method, initialize an empty list to store the result.
+3. Define a helper function, let's name it `dfs`, which will perform depth-first search to generate all possible partitions.
+4. In the `dfs` function, if the current partition `start` is equal to the length of the string `s`, append the current partition to the result list.
+5. Otherwise, iterate through each possible end index of the substring starting from `start` to the end of the string.
+6. Check if the substring from `start` to the current end index is a palindrome. If it is, recursively call the `dfs` function with the updated start index and add the current palindrome substring to the current partition.
+7. After exploring all possible partitions, backtrack by removing the last added substring to explore other possibilities.
+8. Finally, return the result list containing all possible palindrome partitions.
+
+Here's how the `Solution` class would look like in Python:
+
+```python
+class Solution:
+    def partition(self, s: str) -> List[List[str]]:
+        result = []
+        
+        def dfs(start, partition):
+            if start == len(s):
+                result.append(partition[:])
+                return
+            
+            for end in range(start + 1, len(s) + 1):
+                if s[start:end] == s[start:end][::-1]:
+                    partition.append(s[start:end])
+                    dfs(end, partition)
+                    partition.pop()
+        
+        dfs(0, [])
+        return result
+
+# Example usage:
+solution = Solution()
+print(solution.partition("aab"))  # Output: [["a","a","b"],["aa","b"]]
+print(solution.partition("a"))     # Output: [["a"]]
+```
+
+This solution utilizes backtracking to efficiently generate all possible palindrome partitions of the given string `s`.
\ No newline at end of file
diff --git a/g0101_0200/s0136_single_number/readme.md b/g0101_0200/s0136_single_number/readme.md
new file mode 100644
index 0000000..832c6b9
--- /dev/null
+++ b/g0101_0200/s0136_single_number/readme.md
@@ -0,0 +1,59 @@
+136\. Single Number
+
+Easy
+
+Given a **non-empty** array of integers `nums`, every element appears _twice_ except for one. Find that single one.
+
+You must implement a solution with a linear runtime complexity and use only constant extra space.
+
+**Example 1:**
+
+**Input:** nums = [2,2,1]
+
+**Output:** 1 
+
+**Example 2:**
+
+**Input:** nums = [4,1,2,1,2]
+
+**Output:** 4 
+
+**Example 3:**
+
+**Input:** nums = [1]
+
+**Output:** 1 
+
+**Constraints:**
+
+*   <code>1 <= nums.length <= 3 * 10<sup>4</sup></code>
+*   <code>-3 * 10<sup>4</sup> <= nums[i] <= 3 * 10<sup>4</sup></code>
+*   Each element in the array appears twice except for one element which appears only once.
+
+To solve this problem with the `Solution` class, which requires linear runtime complexity and constant extra space, we can utilize the bitwise XOR operation. Here are the steps:
+
+1. Define the `Solution` class with a method `singleNumber` that takes a list of integers `nums` as input and returns the single number that appears only once.
+2. Within the `singleNumber` method, initialize a variable `result` to 0.
+3. Iterate through each element in the `nums` list.
+4. Perform bitwise XOR operation between `result` and the current element.
+5. After iterating through all elements, `result` will contain the single number that appears only once due to the properties of XOR operation.
+6. Finally, return the `result`.
+
+Here's how the `Solution` class would look like in Python:
+
+```python
+class Solution:
+    def singleNumber(self, nums: List[int]) -> int:
+        result = 0
+        for num in nums:
+            result ^= num
+        return result
+
+# Example usage:
+solution = Solution()
+print(solution.singleNumber([2, 2, 1]))      # Output: 1
+print(solution.singleNumber([4, 1, 2, 1, 2]))# Output: 4
+print(solution.singleNumber([1]))            # Output: 1
+```
+
+This solution leverages the bitwise XOR operation to find the single number that appears only once in the array, achieving linear runtime complexity and constant extra space usage.
\ No newline at end of file
diff --git a/g0101_0200/s0138_copy_list_with_random_pointer/readme.md b/g0101_0200/s0138_copy_list_with_random_pointer/readme.md
new file mode 100644
index 0000000..3271582
--- /dev/null
+++ b/g0101_0200/s0138_copy_list_with_random_pointer/readme.md
@@ -0,0 +1,94 @@
+138\. Copy List with Random Pointer
+
+Medium
+
+A linked list of length `n` is given such that each node contains an additional random pointer, which could point to any node in the list, or `null`.
+
+Construct a [**deep copy**](https://en.wikipedia.org/wiki/Object_copying#Deep_copy) of the list. The deep copy should consist of exactly `n` **brand new** nodes, where each new node has its value set to the value of its corresponding original node. Both the `next` and `random` pointer of the new nodes should point to new nodes in the copied list such that the pointers in the original list and copied list represent the same list state. **None of the pointers in the new list should point to nodes in the original list**.
+
+For example, if there are two nodes `X` and `Y` in the original list, where `X.random --> Y`, then for the corresponding two nodes `x` and `y` in the copied list, `x.random --> y`.
+
+Return _the head of the copied linked list_.
+
+The linked list is represented in the input/output as a list of `n` nodes. Each node is represented as a pair of `[val, random_index]` where:
+
+*   `val`: an integer representing `Node.val`
+*   `random_index`: the index of the node (range from `0` to `n-1`) that the `random` pointer points to, or `null` if it does not point to any node.
+
+Your code will **only** be given the `head` of the original linked list.
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2019/12/18/e1.png)
+
+**Input:** head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
+
+**Output:** [[7,null],[13,0],[11,4],[10,2],[1,0]] 
+
+**Example 2:**
+
+![](https://assets.leetcode.com/uploads/2019/12/18/e2.png)
+
+**Input:** head = [[1,1],[2,1]]
+
+**Output:** [[1,1],[2,1]] 
+
+**Example 3:**
+
+**![](https://assets.leetcode.com/uploads/2019/12/18/e3.png)**
+
+**Input:** head = [[3,null],[3,0],[3,null]]
+
+**Output:** [[3,null],[3,0],[3,null]] 
+
+**Example 4:**
+
+**Input:** head = []
+
+**Output:** []
+
+**Explanation:** The given linked list is empty (null pointer), so return null. 
+
+**Constraints:**
+
+*   `0 <= n <= 1000`
+*   `-10000 <= Node.val <= 10000`
+*   `Node.random` is `null` or is pointing to some node in the linked list.
+
+To solve this problem with the `Solution` class, we can use a hashmap to keep track of the mapping between original nodes and their corresponding copied nodes. Here are the steps:
+
+1. Define the `Solution` class with a method `copyRandomList` that takes the head of the original linked list as input and returns the head of the copied linked list.
+2. Within the `copyRandomList` method, if the input `head` is `None`, return `None` as the copied list is empty.
+3. Initialize an empty hashmap to store the mapping between original nodes and copied nodes.
+4. Iterate through the original linked list and create a copied node for each original node. Set the value of the copied node to be the same as the original node and set both `next` and `random` pointers of the copied node to `None`.
+5. Store the mapping between original nodes and copied nodes in the hashmap.
+6. Iterate through the original linked list again and update the `next` and `random` pointers of copied nodes according to the mapping stored in the hashmap.
+7. Finally, return the head of the copied linked list.
+
+Here's how the `Solution` class would look like in Python:
+
+```python
+class Solution:
+    def copyRandomList(self, head: 'Node') -> 'Node':
+        if not head:
+            return None
+        
+        mapping = {}
+        
+        # Create copies of nodes without pointers
+        current = head
+        while current:
+            mapping[current] = Node(current.val)
+            current = current.next
+        
+        # Assign pointers for each copied node
+        current = head
+        while current:
+            mapping[current].next = mapping.get(current.next)
+            mapping[current].random = mapping.get(current.random)
+            current = current.next
+        
+        return mapping[head]
+```
+
+Make sure to define the `Node` class before using it in the `copyRandomList` method. This solution constructs a deep copy of the original linked list while maintaining the relationships between nodes as specified.
\ No newline at end of file
diff --git a/g0101_0200/s0139_word_break/readme.md b/g0101_0200/s0139_word_break/readme.md
new file mode 100644
index 0000000..017c8ed
--- /dev/null
+++ b/g0101_0200/s0139_word_break/readme.md
@@ -0,0 +1,72 @@
+139\. Word Break
+
+Medium
+
+Given a string `s` and a dictionary of strings `wordDict`, return `true` if `s` can be segmented into a space-separated sequence of one or more dictionary words.
+
+**Note** that the same word in the dictionary may be reused multiple times in the segmentation.
+
+**Example 1:**
+
+**Input:** s = "leetcode", wordDict = ["leet","code"]
+
+**Output:** true
+
+**Explanation:** Return true because "leetcode" can be segmented as "leet code". 
+
+**Example 2:**
+
+**Input:** s = "applepenapple", wordDict = ["apple","pen"]
+
+**Output:** true
+
+**Explanation:** Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word. 
+
+**Example 3:**
+
+**Input:** s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
+
+**Output:** false 
+
+**Constraints:**
+
+*   `1 <= s.length <= 300`
+*   `1 <= wordDict.length <= 1000`
+*   `1 <= wordDict[i].length <= 20`
+*   `s` and `wordDict[i]` consist of only lowercase English letters.
+*   All the strings of `wordDict` are **unique**.
+
+To solve this problem with the `Solution` class, we can use dynamic programming to efficiently determine whether the string `s` can be segmented into words from the dictionary `wordDict`. Here are the steps:
+
+1. Define the `Solution` class with a method `wordBreak` that takes a string `s` and a list of strings `wordDict` as input and returns a boolean indicating whether `s` can be segmented into words from `wordDict`.
+2. Initialize a boolean list `dp` of size `len(s) + 1`, where `dp[i]` represents whether the substring `s[:i]` can be segmented into words from `wordDict`.
+3. Set `dp[0]` to `True` since an empty string can always be segmented.
+4. Iterate `i` from 1 to `len(s)`, and for each index `i`, iterate `j` from 0 to `i`.
+5. Check if the substring `s[j:i]` exists in `wordDict` and if `dp[j]` is `True`. If both conditions are met, set `dp[i]` to `True`.
+6. After completing the iterations, return `dp[len(s)]`, which represents whether the entire string `s` can be segmented into words from `wordDict`.
+
+Here's how the `Solution` class would look like in Python:
+
+```python
+class Solution:
+    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
+        word_set = set(wordDict)
+        dp = [False] * (len(s) + 1)
+        dp[0] = True
+        
+        for i in range(1, len(s) + 1):
+            for j in range(i):
+                if dp[j] and s[j:i] in word_set:
+                    dp[i] = True
+                    break
+        
+        return dp[len(s)]
+
+# Example usage:
+solution = Solution()
+print(solution.wordBreak("leetcode", ["leet", "code"]))         # Output: True
+print(solution.wordBreak("applepenapple", ["apple", "pen"]))    # Output: True
+print(solution.wordBreak("catsandog", ["cats", "dog", "sand", "and", "cat"]))  # Output: False
+```
+
+This solution effectively utilizes dynamic programming to determine whether the string `s` can be segmented into words from the dictionary `wordDict`, satisfying the constraints provided in the problem statement.
\ No newline at end of file
diff --git a/g0101_0200/s0141_linked_list_cycle/readme.md b/g0101_0200/s0141_linked_list_cycle/readme.md
new file mode 100644
index 0000000..ffdef60
--- /dev/null
+++ b/g0101_0200/s0141_linked_list_cycle/readme.md
@@ -0,0 +1,101 @@
+141\. Linked List Cycle
+
+Easy
+
+Given `head`, the head of a linked list, determine if the linked list has a cycle in it.
+
+There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the `next` pointer. Internally, `pos` is used to denote the index of the node that tail's `next` pointer is connected to. **Note that `pos` is not passed as a parameter**.
+
+Return `true` _if there is a cycle in the linked list_. Otherwise, return `false`.
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist.png)
+
+**Input:** head = [3,2,0,-4], pos = 1
+
+**Output:** true
+
+**Explanation:** There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed). 
+
+**Example 2:**
+
+![](https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist_test2.png)
+
+**Input:** head = [1,2], pos = 0
+
+**Output:** true
+
+**Explanation:** There is a cycle in the linked list, where the tail connects to the 0th node. 
+
+**Example 3:**
+
+![](https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist_test3.png)
+
+**Input:** head = [1], pos = -1
+
+**Output:** false
+
+**Explanation:** There is no cycle in the linked list. 
+
+**Constraints:**
+
+*   The number of the nodes in the list is in the range <code>[0, 10<sup>4</sup>]</code>.
+*   <code>-10<sup>5</sup> <= Node.val <= 10<sup>5</sup></code>
+*   `pos` is `-1` or a **valid index** in the linked-list.
+
+**Follow up:** Can you solve it using `O(1)` (i.e. constant) memory?
+
+To solve this problem with the `Solution` class, we can use Floyd's Tortoise and Hare algorithm, also known as the "slow and fast pointers" approach. Here are the steps:
+
+1. Define the `Solution` class with a method `hasCycle` that takes the head of a linked list as input and returns a boolean indicating whether the linked list has a cycle.
+2. Initialize two pointers, `slow` and `fast`, both pointing to the head of the linked list.
+3. Iterate through the linked list using the slow and fast pointers.
+4. Move the slow pointer one step at a time and the fast pointer two steps at a time.
+5. If there is a cycle in the linked list, eventually the fast pointer will meet the slow pointer at some point.
+6. If the fast pointer reaches the end of the list (`None`), it means there is no cycle, so return `False`.
+7. If the fast and slow pointers meet, it means there is a cycle, so return `True`.
+
+Here's how the `Solution` class would look like in Python:
+
+```python
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+
+class Solution:
+    def hasCycle(self, head: ListNode) -> bool:
+        if not head or not head.next:
+            return False
+        
+        slow = head
+        fast = head.next
+        
+        while slow != fast:
+            if not fast or not fast.next:
+                return False
+            slow = slow.next
+            fast = fast.next.next
+        
+        return True
+
+# Example usage:
+solution = Solution()
+head1 = ListNode(3)
+head1.next = ListNode(2)
+head1.next.next = ListNode(0)
+head1.next.next.next = ListNode(-4)
+head1.next.next.next.next = head1.next  # creates a cycle
+print(solution.hasCycle(head1))  # Output: True
+
+head2 = ListNode(1)
+head2.next = ListNode(2)
+head2.next.next = head2  # creates a cycle
+print(solution.hasCycle(head2))  # Output: True
+
+head3 = ListNode(1)
+print(solution.hasCycle(head3))  # Output: False
+```
+
+This solution effectively uses Floyd's Tortoise and Hare algorithm to detect whether there is a cycle in the linked list, satisfying the constraints provided in the problem statement.
\ No newline at end of file
