diff --git a/g0001_0100/s0019_remove_nth_node_from_end_of_list/readme.md b/g0001_0100/s0019_remove_nth_node_from_end_of_list/readme.md
new file mode 100644
index 0000000..7be5129
--- /dev/null
+++ b/g0001_0100/s0019_remove_nth_node_from_end_of_list/readme.md
@@ -0,0 +1,109 @@
+19\. Remove Nth Node From End of List
+
+Medium
+
+Given the `head` of a linked list, remove the `nth` node from the end of the list and return its head.
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2020/10/03/remove_ex1.jpg)
+
+**Input:** head = [1,2,3,4,5], n = 2
+
+**Output:** [1,2,3,5] 
+
+**Example 2:**
+
+**Input:** head = [1], n = 1
+
+**Output:** [] 
+
+**Example 3:**
+
+**Input:** head = [1,2], n = 1
+
+**Output:** [1] 
+
+**Constraints:**
+
+*   The number of nodes in the list is `sz`.
+*   `1 <= sz <= 30`
+*   `0 <= Node.val <= 100`
+*   `1 <= n <= sz`
+
+**Follow up:** Could you do this in one pass?
+
+Here are the steps to solve the "Remove Nth Node From End of List" problem:
+
+### Approach:
+
+1. **Initialize Pointers:**
+   - Initialize two pointers, `fast` and `slow`, both initially pointing to the head of the linked list.
+
+2. **Move Fast Pointer:**
+   - Move the `fast` pointer `n` nodes ahead.
+
+3. **Handle Edge Case:**
+   - If the `fast` pointer becomes `None` after moving `n` nodes, it means the node to be removed is the head of the list. In this case, return `head.next`.
+
+4. **Move Both Pointers Until Fast Reaches End:**
+   - Move both `fast` and `slow` pointers one node at a time until the `fast` pointer reaches the end of the list.
+
+5. **Remove Nth Node:**
+   - Update the next pointer of the `slow` pointer to skip the node to be removed.
+
+6. **Return Updated Head:**
+   - Return the head of the modified linked list.
+
+### Python Code:
+
+```python
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
+class Solution:
+    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
+        # Initialize pointers
+        fast = slow = head
+
+        # Move fast pointer n nodes ahead
+        for _ in range(n):
+            fast = fast.next
+
+        # Handle case where the node to be removed is the head
+        if not fast:
+            return head.next
+
+        # Move both pointers until fast reaches the end
+        while fast.next:
+            fast = fast.next
+            slow = slow.next
+
+        # Remove nth node
+        slow.next = slow.next.next
+
+        # Return updated head
+        return head
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+head1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
+n1 = 2
+result1 = solution.removeNthFromEnd(head1, n1)  # Output: ListNode(1, ListNode(2, ListNode(3, ListNode(5))))
+
+# Example 2:
+head2 = ListNode(1)
+n2 = 1
+result2 = solution.removeNthFromEnd(head2, n2)  # Output: None (empty list)
+
+# Example 3:
+head3 = ListNode(1, ListNode(2))
+n3 = 1
+result3 = solution.removeNthFromEnd(head3, n3)  # Output: ListNode(1)
+```
+
+This code defines a `ListNode` class representing a node in the linked list and a `Solution` class with a method `removeNthFromEnd` that takes the head of the linked list and an integer `n` as input, removes the `nth` node from the end of the list, and returns the head of the modified list. The example usage demonstrates how to create instances of the `ListNode` class and call the `removeNthFromEnd` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0020_valid_parentheses/readme.md b/g0001_0100/s0020_valid_parentheses/readme.md
new file mode 100644
index 0000000..62dfe77
--- /dev/null
+++ b/g0001_0100/s0020_valid_parentheses/readme.md
@@ -0,0 +1,117 @@
+20\. Valid Parentheses
+
+Easy
+
+Given a string `s` containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.
+
+An input string is valid if:
+
+1.  Open brackets must be closed by the same type of brackets.
+2.  Open brackets must be closed in the correct order.
+
+**Example 1:**
+
+**Input:** s = "()"
+
+**Output:** true 
+
+**Example 2:**
+
+**Input:** s = "()[]{}"
+
+**Output:** true 
+
+**Example 3:**
+
+**Input:** s = "(]"
+
+**Output:** false 
+
+**Example 4:**
+
+**Input:** s = "([)]"
+
+**Output:** false 
+
+**Example 5:**
+
+**Input:** s = "{[]}"
+
+**Output:** true 
+
+**Constraints:**
+
+*   <code>1 <= s.length <= 10<sup>4</sup></code>
+*   `s` consists of parentheses only `'()[]{}'`.
+
+Here are the steps to solve the "Valid Parentheses" problem:
+
+### Approach:
+
+1. **Initialize Stack:**
+   - Initialize an empty stack to keep track of the opening brackets.
+
+2. **Iterate Through Characters:**
+   - Iterate through each character in the input string `s`.
+
+3. **Check for Opening Bracket:**
+   - If the current character is an opening bracket (`'('`, `'{'`, or `'['`), push it onto the stack.
+
+4. **Check for Closing Bracket:**
+   - If the current character is a closing bracket (`')'`, `'}'`, or `']'`), check if the stack is empty. If it is, return `False` as there is no corresponding opening bracket.
+
+5. **Check Matching Brackets:**
+   - Pop the top element from the stack and check if it matches the corresponding opening bracket for the current closing bracket. If not, return `False`.
+
+6. **Check for Empty Stack:**
+   - After iterating through all characters, check if the stack is empty. If it is, return `True`; otherwise, return `False`.
+
+### Python Code:
+
+```python
+class Solution:
+    def isValid(self, s: str) -> bool:
+        # Initialize stack
+        stack = []
+
+        # Define mapping of opening to closing brackets
+        bracket_mapping = {')': '(', '}': '{', ']': '['}
+
+        # Iterate through characters
+        for char in s:
+            # Check for opening bracket
+            if char in bracket_mapping.values():
+                stack.append(char)
+            else:
+                # Check for closing bracket
+                if not stack or stack.pop() != bracket_mapping[char]:
+                    return False
+
+        # Check for empty stack
+        return not stack
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+input1 = "()"
+result1 = solution.isValid(input1)  # Output: True
+
+# Example 2:
+input2 = "()[]{}"
+result2 = solution.isValid(input2)  # Output: True
+
+# Example 3:
+input3 = "(]"
+result3 = solution.isValid(input3)  # Output: False
+
+# Example 4:
+input4 = "([)]"
+result4 = solution.isValid(input4)  # Output: False
+
+# Example 5:
+input5 = "{[]}"
+result5 = solution.isValid(input5)  # Output: True
+```
+
+This code defines a `Solution` class with a method `isValid` that takes a string `s` as input and returns `True` if the parentheses in the input string are valid and `False` otherwise. The example usage demonstrates how to create an instance of the `Solution` class and call the `isValid` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0021_merge_two_sorted_lists/readme.md b/g0001_0100/s0021_merge_two_sorted_lists/readme.md
new file mode 100644
index 0000000..12820c3
--- /dev/null
+++ b/g0001_0100/s0021_merge_two_sorted_lists/readme.md
@@ -0,0 +1,106 @@
+21\. Merge Two Sorted Lists
+
+Easy
+
+Merge two sorted linked lists and return it as a **sorted** list. The list should be made by splicing together the nodes of the first two lists.
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2020/10/03/merge_ex1.jpg)
+
+**Input:** l1 = [1,2,4], l2 = [1,3,4]
+
+**Output:** [1,1,2,3,4,4] 
+
+**Example 2:**
+
+**Input:** l1 = [], l2 = []
+
+**Output:** [] 
+
+**Example 3:**
+
+**Input:** l1 = [], l2 = [0]
+
+**Output:** [0] 
+
+**Constraints:**
+
+*   The number of nodes in both lists is in the range `[0, 50]`.
+*   `-100 <= Node.val <= 100`
+*   Both `l1` and `l2` are sorted in **non-decreasing** order.
+
+Here are the steps to solve the "Merge Two Sorted Lists" problem:
+
+### Approach:
+
+1. **Initialize Dummy Node:**
+   - Initialize a dummy node to simplify the code. The dummy node's next pointer will point to the head of the merged list.
+
+2. **Initialize Pointers:**
+   - Initialize pointers `curr` and `prev` initially pointing to the dummy node.
+
+3. **Merge Lists:**
+   - Iterate until either `l1` or `l2` becomes `None`. In each iteration:
+     - Compare the values of the current nodes in `l1` and `l2`.
+     - Connect the smaller node to the merged list.
+     - Move the corresponding pointer (`l1` or `l2`) to its next node.
+     - Move the `curr` pointer to the newly added node.
+
+4. **Handle Remaining Nodes:**
+   - After the loop, if there are remaining nodes in either `l1` or `l2`, connect them to the merged list.
+
+5. **Return Merged List:**
+   - Return the next of the dummy node, which is the head of the merged list.
+
+### Python Code:
+
+```python
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
+class Solution:
+    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
+        # Initialize dummy node
+        dummy = ListNode()
+        # Initialize pointers
+        curr = dummy
+        # Merge lists
+        while l1 and l2:
+            if l1.val < l2.val:
+                curr.next = l1
+                l1 = l1.next
+            else:
+                curr.next = l2
+                l2 = l2.next
+            curr = curr.next
+        # Handle remaining nodes
+        if l1:
+            curr.next = l1
+        elif l2:
+            curr.next = l2
+        # Return merged list
+        return dummy.next
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+l1_1 = ListNode(1, ListNode(2, ListNode(4)))
+l2_1 = ListNode(1, ListNode(3, ListNode(4)))
+result1 = solution.mergeTwoLists(l1_1, l2_1)  # Output: ListNode(1, ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(4))))))
+
+# Example 2:
+l1_2 = None
+l2_2 = None
+result2 = solution.mergeTwoLists(l1_2, l2_2)  # Output: None (empty list)
+
+# Example 3:
+l1_3 = None
+l2_3 = ListNode(0)
+result3 = solution.mergeTwoLists(l1_3, l2_3)  # Output: ListNode(0)
+```
+
+This code defines a `ListNode` class representing a node in the linked list and a `Solution` class with a method `mergeTwoLists` that takes two sorted linked lists (`l1` and `l2`) as input and returns a new sorted linked list obtained by merging the nodes of `l1` and `l2`. The example usage demonstrates how to create instances of the `ListNode` class and call the `mergeTwoLists` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0022_generate_parentheses/readme.md b/g0001_0100/s0022_generate_parentheses/readme.md
new file mode 100644
index 0000000..2b127e4
--- /dev/null
+++ b/g0001_0100/s0022_generate_parentheses/readme.md
@@ -0,0 +1,84 @@
+22\. Generate Parentheses
+
+Medium
+
+Given `n` pairs of parentheses, write a function to _generate all combinations of well-formed parentheses_.
+
+**Example 1:**
+
+**Input:** n = 3
+
+**Output:** ["((()))","(()())","(())()","()(())","()()()"] 
+
+**Example 2:**
+
+**Input:** n = 1
+
+**Output:** ["()"] 
+
+**Constraints:**
+
+*   `1 <= n <= 8`
+
+Here are the steps to solve the "Generate Parentheses" problem:
+
+### Approach:
+
+1. **Initialize Result List:**
+   - Initialize an empty list `result` to store the generated combinations.
+
+2. **Define Recursive Function:**
+   - Define a recursive function `generateParenthesisHelper` that takes parameters:
+     - `current`: the current combination being built.
+     - `left`: the remaining count of open parentheses.
+     - `right`: the remaining count of close parentheses.
+
+3. **Base Case:**
+   - If both `left` and `right` become zero, add the current combination to the `result` list.
+
+4. **Recursive Calls:**
+   - If `left` is greater than zero, make a recursive call with one less open parenthesis and the current combination appended with an open parenthesis.
+   - If `right` is greater than `left`, make a recursive call with one less close parenthesis and the current combination appended with a close parenthesis.
+
+5. **Initialize:**
+   - Start the recursion by calling the `generateParenthesisHelper` function with an empty string (`current`), the total number of open parentheses (`n`), and the total number of close parentheses (`n`).
+
+6. **Return Result:**
+   - Return the `result` list containing all the valid combinations.
+
+### Python Code:
+
+```python
+class Solution:
+    def generateParenthesis(self, n: int):
+        def generateParenthesisHelper(current, left, right):
+            # Base case: If both left and right are zero, add the current combination to result
+            if left == 0 and right == 0:
+                result.append(current)
+                return
+            # Recursive calls
+            if left > 0:
+                generateParenthesisHelper(current + '(', left - 1, right)
+            if right > left:
+                generateParenthesisHelper(current + ')', left, right - 1)
+
+        # Initialize result list
+        result = []
+        # Start recursion
+        generateParenthesisHelper('', n, n)
+        # Return result list
+        return result
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+n1 = 3
+result1 = solution.generateParenthesis(n1)  # Output: ["((()))","(()())","(())()","()(())","()()()"]
+
+# Example 2:
+n2 = 1
+result2 = solution.generateParenthesis(n2)  # Output: ["()"]
+```
+
+This code defines a `Solution` class with a method `generateParenthesis` that takes an integer `n` as input and returns a list containing all combinations of well-formed parentheses for `n` pairs. The example usage demonstrates how to create an instance of the `Solution` class and call the `generateParenthesis` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0023_merge_k_sorted_lists/readme.md b/g0001_0100/s0023_merge_k_sorted_lists/readme.md
new file mode 100644
index 0000000..32ef43d
--- /dev/null
+++ b/g0001_0100/s0023_merge_k_sorted_lists/readme.md
@@ -0,0 +1,108 @@
+23\. Merge k Sorted Lists
+
+Hard
+
+You are given an array of `k` linked-lists `lists`, each linked-list is sorted in ascending order.
+
+_Merge all the linked-lists into one sorted linked-list and return it._
+
+**Example 1:**
+
+**Input:** lists = [[1,4,5],[1,3,4],[2,6]]
+
+**Output:** [1,1,2,3,4,4,5,6]
+
+**Explanation:** The linked-lists are: [ 1->4->5, 1->3->4, 2->6 ] merging them into one sorted list: 1->1->2->3->4->4->5->6 
+
+**Example 2:**
+
+**Input:** lists = []
+
+**Output:** [] 
+
+**Example 3:**
+
+**Input:** lists = [[]]
+
+**Output:** [] 
+
+**Constraints:**
+
+*   `k == lists.length`
+*   `0 <= k <= 10^4`
+*   `0 <= lists[i].length <= 500`
+*   `-10^4 <= lists[i][j] <= 10^4`
+*   `lists[i]` is sorted in **ascending order**.
+*   The sum of `lists[i].length` won't exceed `10^4`.
+
+To solve the "Merge k Sorted Lists" problem, you can follow these steps:
+
+### Approach:
+
+1. **Initialize a Priority Queue (Min-Heap):**
+   - Initialize a priority queue (min-heap) to store nodes from all linked lists based on their values.
+
+2. **Populate Priority Queue:**
+   - Iterate through each linked list and insert the first node (if not None) from each list into the priority queue.
+
+3. **Merge Lists using Priority Queue:**
+   - While the priority queue is not empty:
+     - Pop the smallest node from the priority queue.
+     - Append the node's value to the result list.
+     - If the node has a next element, insert the next node into the priority queue.
+
+4. **Return Result List:**
+   - Return the merged result list.
+
+### Python Code:
+
+```python
+import heapq
+
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
+class Solution:
+    def mergeKLists(self, lists):
+        # Initialize a priority queue
+        heap = []
+        
+        # Populate priority queue with the first node from each list
+        for i, lst in enumerate(lists):
+            if lst:
+                heapq.heappush(heap, (lst.val, i, lst))
+
+        # Initialize result dummy node and pointer
+        result_dummy = ListNode()
+        current = result_dummy
+
+        # Merge lists using priority queue
+        while heap:
+            val, i, node = heapq.heappop(heap)
+            current.next = ListNode(val)
+            current = current.next
+            if node.next:
+                heapq.heappush(heap, (node.next.val, i, node.next))
+
+        # Return merged result
+        return result_dummy.next
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+lists1 = [ListNode(1, ListNode(4, ListNode(5))), ListNode(1, ListNode(3, ListNode(4))), ListNode(2, ListNode(6))]
+result1 = solution.mergeKLists(lists1)  # Output: ListNode(1, ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(4, ListNode(5, ListNode(6))))))))
+
+# Example 2:
+lists2 = []
+result2 = solution.mergeKLists(lists2)  # Output: None
+
+# Example 3:
+lists3 = [[]]
+result3 = solution.mergeKLists(lists3)  # Output: None
+```
+
+This code defines a `Solution` class with a method `mergeKLists` that takes a list of linked lists as input and returns a merged sorted linked list. The example usage demonstrates how to create an instance of the `Solution` class and call the `mergeKLists` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0024_swap_nodes_in_pairs/readme.md b/g0001_0100/s0024_swap_nodes_in_pairs/readme.md
new file mode 100644
index 0000000..9fc0b94
--- /dev/null
+++ b/g0001_0100/s0024_swap_nodes_in_pairs/readme.md
@@ -0,0 +1,102 @@
+24\. Swap Nodes in Pairs
+
+Medium
+
+Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list's nodes (i.e., only nodes themselves may be changed.)
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2020/10/03/swap_ex1.jpg)
+
+**Input:** head = [1,2,3,4]
+
+**Output:** [2,1,4,3] 
+
+**Example 2:**
+
+**Input:** head = []
+
+**Output:** [] 
+
+**Example 3:**
+
+**Input:** head = [1]
+
+**Output:** [1] 
+
+**Constraints:**
+
+*   The number of nodes in the list is in the range `[0, 100]`.
+*   `0 <= Node.val <= 100`
+
+To solve the "Swap Nodes in Pairs" problem, you can follow these steps:
+
+### Approach:
+
+1. **Initialize a Dummy Node:**
+   - Create a dummy node to simplify handling edge cases and to serve as the new head of the modified linked list.
+
+2. **Initialize Pointers:**
+   - Initialize three pointers: `prev`, `current`, and `next`.
+
+3. **Iterate through Pairs:**
+   - Use a loop to iterate through the linked list in pairs.
+   - Inside the loop:
+      - Update `prev.next` to point to the second node in the pair (`next`).
+      - Update `current.next` to point to the node after the pair (`next.next`).
+      - Update `next.next` to point to the first node in the pair (`current`).
+      - Move `prev`, `current`, and `next` pointers to their next positions for the next pair.
+
+4. **Return Modified Head:**
+   - Return the `dummy.next` as the new head of the modified linked list.
+
+### Python Code:
+
+```python
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
+class Solution:
+    def swapPairs(self, head):
+        # Initialize a dummy node
+        dummy = ListNode(0)
+        dummy.next = head
+        prev = dummy
+
+        # Iterate through pairs
+        while head and head.next:
+            # Initialize pointers
+            current = head
+            next_node = head.next
+
+            # Swap pairs
+            prev.next = next_node
+            current.next = next_node.next
+            next_node.next = current
+
+            # Move pointers for the next pair
+            prev = current
+            head = current.next
+
+        # Return modified head
+        return dummy.next
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+head1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4))))
+result1 = solution.swapPairs(head1)  # Output: ListNode(2, ListNode(1, ListNode(4, ListNode(3))))
+
+# Example 2:
+head2 = None
+result2 = solution.swapPairs(head2)  # Output: None
+
+# Example 3:
+head3 = ListNode(1)
+result3 = solution.swapPairs(head3)  # Output: ListNode(1)
+```
+
+This code defines a `Solution` class with a method `swapPairs` that takes a linked list as input and swaps every two adjacent nodes. The example usage demonstrates how to create an instance of the `Solution` class and call the `swapPairs` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0025_reverse_nodes_in_k_group/readme.md b/g0001_0100/s0025_reverse_nodes_in_k_group/readme.md
new file mode 100644
index 0000000..ace8deb
--- /dev/null
+++ b/g0001_0100/s0025_reverse_nodes_in_k_group/readme.md
@@ -0,0 +1,142 @@
+25\. Reverse Nodes in k-Group
+
+Hard
+
+Given a linked list, reverse the nodes of a linked list _k_ at a time and return its modified list.
+
+_k_ is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of _k_ then left-out nodes, in the end, should remain as it is.
+
+You may not alter the values in the list's nodes, only nodes themselves may be changed.
+
+**Example 1:**
+
+![](https://assets.leetcode.com/uploads/2020/10/03/reverse_ex1.jpg)
+
+**Input:** head = [1,2,3,4,5], k = 2
+
+**Output:** [2,1,4,3,5] 
+
+**Example 2:**
+
+![](https://assets.leetcode.com/uploads/2020/10/03/reverse_ex2.jpg)
+
+**Input:** head = [1,2,3,4,5], k = 3
+
+**Output:** [3,2,1,4,5] 
+
+**Example 3:**
+
+**Input:** head = [1,2,3,4,5], k = 1
+
+**Output:** [1,2,3,4,5] 
+
+**Example 4:**
+
+**Input:** head = [1], k = 1
+
+**Output:** [1] 
+
+**Constraints:**
+
+*   The number of nodes in the list is in the range `sz`.
+*   `1 <= sz <= 5000`
+*   `0 <= Node.val <= 1000`
+*   `1 <= k <= sz`
+
+**Follow-up:** Can you solve the problem in O(1) extra memory space?
+
+To solve the "Reverse Nodes in k-Group" problem, you can use the following approach:
+
+### Approach:
+
+1. **Check if Reversal is Possible:**
+   - Before reversing, check if there are at least `k` nodes remaining in the linked list.
+
+2. **Reverse Nodes:**
+   - Reverse the next `k` nodes of the linked list.
+
+3. **Connect the Reversed Portion:**
+   - Connect the reversed portion to the previous part of the linked list.
+
+4. **Update Pointers:**
+   - Move the pointers to their correct positions for the next iteration.
+
+5. **Repeat:**
+   - Repeat the process until there are fewer than `k` nodes left.
+
+6. **Return Result:**
+   - Return the modified head of the linked list.
+
+### Python Code:
+
+```python
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
+class Solution:
+    def reverseKGroup(self, head, k):
+        # Function to reverse a linked list
+        def reverseList(start, end):
+            prev, curr = None, start
+            while curr != end:
+                next_node = curr.next
+                curr.next = prev
+                prev = curr
+                curr = next_node
+            return prev
+
+        # Initialize pointers
+        dummy = ListNode(0)
+        dummy.next = head
+        prev, curr = dummy, head
+
+        # Find the length of the linked list
+        length = 0
+        while head:
+            length += 1
+            head = head.next
+
+        # Reverse nodes in k-group
+        while length >= k:
+            end = curr
+            for _ in range(k - 1):
+                end = end.next
+
+            # Reverse k nodes
+            next_start = end.next
+            reversed_start = reverseList(curr, next_start)
+
+            # Connect reversed portion to the previous part
+            prev.next = reversed_start
+            curr.next = next_start
+
+            # Move pointers for the next iteration
+            prev, curr = curr, next_start
+            length -= k
+
+        # Return the modified head
+        return dummy.next
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+head1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
+result1 = solution.reverseKGroup(head1, 2)  # Output: ListNode(2, ListNode(1, ListNode(4, ListNode(3, ListNode(5))))))
+
+# Example 2:
+head2 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
+result2 = solution.reverseKGroup(head2, 3)  # Output: ListNode(3, ListNode(2, ListNode(1, ListNode(4, ListNode(5))))))
+
+# Example 3:
+head3 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
+result3 = solution.reverseKGroup(head3, 1)  # Output: ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
+
+# Example 4:
+head4 = ListNode(1)
+result4 = solution.reverseKGroup(head4, 1)  # Output: ListNode(1)
+```
+
+This code defines a `Solution` class with a method `reverseKGroup` that takes a linked list and an integer `k` as input and reverses every `k` nodes in the linked list. The example usage demonstrates how to create an instance of the `Solution` class and call the `reverseKGroup` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0031_next_permutation/readme.md b/g0001_0100/s0031_next_permutation/readme.md
new file mode 100644
index 0000000..9db206c
--- /dev/null
+++ b/g0001_0100/s0031_next_permutation/readme.md
@@ -0,0 +1,102 @@
+31\. Next Permutation
+
+Medium
+
+Implement **next permutation**, which rearranges numbers into the lexicographically next greater permutation of numbers.
+
+If such an arrangement is not possible, it must rearrange it as the lowest possible order (i.e., sorted in ascending order).
+
+The replacement must be **[in place](http://en.wikipedia.org/wiki/In-place_algorithm)** and use only constant extra memory.
+
+**Example 1:**
+
+**Input:** nums = [1,2,3]
+
+**Output:** [1,3,2] 
+
+**Example 2:**
+
+**Input:** nums = [3,2,1]
+
+**Output:** [1,2,3] 
+
+**Example 3:**
+
+**Input:** nums = [1,1,5]
+
+**Output:** [1,5,1] 
+
+**Example 4:**
+
+**Input:** nums = [1]
+
+**Output:** [1] 
+
+**Constraints:**
+
+*   `1 <= nums.length <= 100`
+*   `0 <= nums[i] <= 100`
+
+To solve the "Next Permutation" problem, you can use the following steps:
+
+### Approach:
+
+1. **Find the First Decreasing Element:**
+   - Starting from the right, find the first pair of adjacent elements `nums[i]` and `nums[i+1]` where `nums[i] < nums[i+1]`. This element `nums[i]` is the first decreasing element.
+
+2. **Find the Smallest Element to the Right of `nums[i]`:**
+   - From the end, find the smallest element to the right of `nums[i]` that is greater than `nums[i]`. Let's call this element `nums[j]`.
+
+3. **Swap `nums[i]` and `nums[j]`:**
+   - Swap the elements `nums[i]` and `nums[j]`.
+
+4. **Reverse the Subarray to the Right of `nums[i]`:**
+   - Reverse the subarray to the right of `nums[i]` to ensure the smallest lexicographically next permutation.
+
+### Python Code:
+
+```python
+class Solution:
+    def nextPermutation(self, nums):
+        # Step 1: Find the first decreasing element
+        i = len(nums) - 2
+        while i >= 0 and nums[i] >= nums[i+1]:
+            i -= 1
+
+        # Step 2: Find the smallest element to the right of nums[i] that is greater than nums[i]
+        if i >= 0:
+            j = len(nums) - 1
+            while nums[j] <= nums[i]:
+                j -= 1
+
+            # Step 3: Swap nums[i] and nums[j]
+            nums[i], nums[j] = nums[j], nums[i]
+
+        # Step 4: Reverse the subarray to the right of nums[i]
+        left, right = i + 1, len(nums) - 1
+        while left < right:
+            nums[left], nums[right] = nums[right], nums[left]
+            left += 1
+            right -= 1
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+nums1 = [1, 2, 3]
+solution.nextPermutation(nums1)  # Output: [1, 3, 2]
+
+# Example 2:
+nums2 = [3, 2, 1]
+solution.nextPermutation(nums2)  # Output: [1, 2, 3]
+
+# Example 3:
+nums3 = [1, 1, 5]
+solution.nextPermutation(nums3)  # Output: [1, 5, 1]
+
+# Example 4:
+nums4 = [1]
+solution.nextPermutation(nums4)  # Output: [1]
+```
+
+This code defines a `Solution` class with a method `nextPermutation` that takes a list of integers `nums` and modifies it to the next lexicographically greater permutation. The example usage demonstrates how to create an instance of the `Solution` class and call the `nextPermutation` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0032_longest_valid_parentheses/readme.md b/g0001_0100/s0032_longest_valid_parentheses/readme.md
new file mode 100644
index 0000000..0ba629d
--- /dev/null
+++ b/g0001_0100/s0032_longest_valid_parentheses/readme.md
@@ -0,0 +1,91 @@
+32\. Longest Valid Parentheses
+
+Hard
+
+Given a string containing just the characters `'('` and `')'`, find the length of the longest valid (well-formed) parentheses substring.
+
+**Example 1:**
+
+**Input:** s = "(()"
+
+**Output:** 2
+
+**Explanation:** The longest valid parentheses substring is "()". 
+
+**Example 2:**
+
+**Input:** s = ")()())"
+
+**Output:** 4
+
+**Explanation:** The longest valid parentheses substring is "()()". 
+
+**Example 3:**
+
+**Input:** s = ""
+
+**Output:** 0 
+
+**Constraints:**
+
+*   <code>0 <= s.length <= 3 * 10<sup>4</sup></code>
+*   `s[i]` is `'('`, or `')'`.
+
+To solve the "Longest Valid Parentheses" problem, you can use the following steps:
+
+### Approach:
+
+1. **Initialize Variables:**
+   - Initialize a variable `max_length` to store the maximum valid parentheses substring length.
+   - Initialize a stack to keep track of indices of opening parentheses.
+
+2. **Traverse the String:**
+   - Iterate through each character in the string.
+   - If the character is `'('`, push its index onto the stack.
+   - If the character is `')'`:
+     - If the stack is not empty, pop an element from the stack.
+     - If the stack becomes empty:
+       - Push the current index onto the stack (marks the start of a potential new valid substring).
+       - Update `max_length` using the difference between the current index and the index popped from the stack.
+     - If the stack is not empty, update `max_length` using the difference between the current index and the index at the top of the stack.
+
+3. **Final Result:**
+   - The value of `max_length` will represent the length of the longest valid parentheses substring.
+
+### Python Code:
+
+```python
+class Solution:
+    def longestValidParentheses(self, s):
+        stack = [-1]  # Initialize the stack with -1 to handle the case when the first parenthesis is ')'
+        max_length = 0
+
+        for i in range(len(s)):
+            if s[i] == '(':
+                stack.append(i)
+            else:  # s[i] == ')'
+                stack.pop()
+                if not stack:
+                    stack.append(i)
+                else:
+                    max_length = max(max_length, i - stack[-1])
+
+        return max_length
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+s1 = "(()"
+print(solution.longestValidParentheses(s1))  # Output: 2
+
+# Example 2:
+s2 = ")()())"
+print(solution.longestValidParentheses(s2))  # Output: 4
+
+# Example 3:
+s3 = ""
+print(solution.longestValidParentheses(s3))  # Output: 0
+```
+
+This code defines a `Solution` class with a method `longestValidParentheses` that takes a string `s` and returns the length of the longest valid parentheses substring. The example usage demonstrates how to create an instance of the `Solution` class and call the `longestValidParentheses` method with different inputs.
\ No newline at end of file
diff --git a/g0001_0100/s0033_search_in_rotated_sorted_array/readme.md b/g0001_0100/s0033_search_in_rotated_sorted_array/readme.md
new file mode 100644
index 0000000..16d02a9
--- /dev/null
+++ b/g0001_0100/s0033_search_in_rotated_sorted_array/readme.md
@@ -0,0 +1,124 @@
+33\. Search in Rotated Sorted Array
+
+Medium
+
+There is an integer array `nums` sorted in ascending order (with **distinct** values).
+
+Prior to being passed to your function, `nums` is **possibly rotated** at an unknown pivot index `k` (`1 <= k < nums.length`) such that the resulting array is `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]` (**0-indexed**). For example, `[0,1,2,4,5,6,7]` might be rotated at pivot index `3` and become `[4,5,6,7,0,1,2]`.
+
+Given the array `nums` **after** the possible rotation and an integer `target`, return _the index of_ `target` _if it is in_ `nums`_, or_ `-1` _if it is not in_ `nums`.
+
+You must write an algorithm with `O(log n)` runtime complexity.
+
+**Example 1:**
+
+**Input:** nums = [4,5,6,7,0,1,2], target = 0
+
+**Output:** 4 
+
+**Example 2:**
+
+**Input:** nums = [4,5,6,7,0,1,2], target = 3
+
+**Output:** -1 
+
+**Example 3:**
+
+**Input:** nums = [1], target = 0
+
+**Output:** -1 
+
+**Constraints:**
+
+*   `1 <= nums.length <= 5000`
+*   <code>-10<sup>4</sup> <= nums[i] <= 10<sup>4</sup></code>
+*   All values of `nums` are **unique**.
+*   `nums` is an ascending array that is possibly rotated.
+*   <code>-10<sup>4</sup> <= target <= 10<sup>4</sup></code>
+
+To solve the "Search in Rotated Sorted Array" problem, you can use a modified binary search algorithm. Here are the steps:
+
+### Approach:
+
+1. **Find the Pivot:**
+   - Use binary search to find the pivot index where the array is rotated.
+   - The pivot is the index where `nums[pivot] > nums[pivot+1]`.
+
+2. **Perform Binary Search:**
+   - Compare the target with the first element of the array.
+   - If the target is greater, perform a binary search in the second half.
+   - If the target is smaller, perform a binary search in the first half.
+
+3. **Binary Search:**
+   - Use a standard binary search algorithm to find the target in the selected half of the array.
+   - Update the mid index and adjust the search space accordingly.
+
+4. **Handle Rotation:**
+   - Adjust the mid index based on the pivot to consider the rotation.
+
+5. **Handle Missing Elements:**
+   - If the target is not found, return -1.
+
+### Python Code:
+
+```python
+class Solution:
+    def search(self, nums, target):
+        # Function to find the index of the pivot
+        def find_pivot(nums):
+            left, right = 0, len(nums) - 1
+
+            while left < right:
+                mid = (left + right) // 2
+
+                if nums[mid] > nums[mid + 1]:
+                    return mid + 1  # Found the pivot
+                elif nums[mid] >= nums[left]:
+                    left = mid + 1
+                else:
+                    right = mid
+
+            return 0  # No rotation, array is not rotated
+
+        # Function to perform binary search in the rotated array
+        def binary_search(nums, target, left, right):
+            while left <= right:
+                mid = (left + right) // 2
+
+                if nums[mid] == target:
+                    return mid
+                elif nums[mid] < target:
+                    left = mid + 1
+                else:
+                    right = mid - 1
+
+            return -1
+
+        pivot = find_pivot(nums)
+
+        # Check which half of the array to search
+        if pivot == 0 or target < nums[0]:
+            return binary_search(nums, target, pivot, len(nums) - 1)
+        else:
+            return binary_search(nums, target, 0, pivot - 1)
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+nums1 = [4, 5, 6, 7, 0, 1, 2]
+target1 = 0
+print(solution.search(nums1, target1))  # Output: 4
+
+# Example 2:
+nums2 = [4, 5, 6, 7, 0, 1, 2]
+target2 = 3
+print(solution.search(nums2, target2))  # Output: -1
+
+# Example 3:
+nums3 = [1]
+target3 = 0
+print(solution.search(nums3, target3))  # Output: -1
+```
+
+This code defines a `Solution` class with methods to find the pivot and perform binary search in the rotated array. The example usage demonstrates how to create an instance of the `Solution` class and call the `search` method with different inputs.
\ No newline at end of file
