diff --git a/src/main/python/g0001_0100/s0001_two_sum/readme.md b/src/main/python/g0001_0100/s0001_two_sum/readme.md
index a0051f3..1e1f5e6 100644
--- a/src/main/python/g0001_0100/s0001_two_sum/readme.md
+++ b/src/main/python/g0001_0100/s0001_two_sum/readme.md
@@ -40,6 +40,69 @@ You can return the answer in any order.
 
 **Follow-up:** Can you come up with an algorithm that is less than <code>O(n<sup>2</sup>)</code> time complexity?
 
+Here are the steps to solve the Two Sum problem:
+
+### Approach:
+
+1. **Create a Dictionary/HashMap:**
+   - Initialize an empty dictionary to store the elements of the array and their corresponding indices.
+
+2. **Iterate through the Array:**
+   - Traverse through the given array `nums` using a loop.
+
+3. **Check Complement:**
+   - For each element `nums[i]`, calculate its complement (i.e., `target - nums[i]`).
+
+4. **Check if Complement exists:**
+   - Check if the complement is already in the dictionary.
+     - If it is, return the indices `[dictionary[complement], i]`.
+     - If not, add the current element and its index to the dictionary.
+
+### Python Code:
+
+```python
+from typing import List
+
+class Solution:
+    def twoSum(self, nums: List[int], target: int) -> List[int]:
+        # Create a dictionary to store elements and their indices
+        num_dict = {}
+        
+        # Iterate through the array
+        for i in range(len(nums)):
+            # Check complement
+            complement = target - nums[i]
+            
+            # Check if complement exists in the dictionary
+            if complement in num_dict:
+                # Return the indices if complement is found
+                return [num_dict[complement], i]
+            
+            # Add the current element and its index to the dictionary
+            num_dict[nums[i]] = i
+        
+        # If no solution is found
+        return None
+
+# Example Usage:
+solution = Solution()
+
+nums1 = [2, 7, 11, 15]
+target1 = 9
+print(solution.twoSum(nums1, target1))  # Output: [0, 1]
+
+nums2 = [3, 2, 4]
+target2 = 6
+print(solution.twoSum(nums2, target2))  # Output: [1, 2]
+
+nums3 = [3, 3]
+target3 = 6
+print(solution.twoSum(nums3, target3))  # Output: [0, 1]
+```
+
+### Time Complexity:
+The time complexity of this algorithm is O(n), where n is the number of elements in the array. The dictionary lookup operation is constant time.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0002_add_two_numbers/readme.md b/src/main/python/g0001_0100/s0002_add_two_numbers/readme.md
index 6336e49..c24c2aa 100644
--- a/src/main/python/g0001_0100/s0002_add_two_numbers/readme.md
+++ b/src/main/python/g0001_0100/s0002_add_two_numbers/readme.md
@@ -37,6 +37,98 @@ You may assume the two numbers do not contain any leading zero, except the numbe
 *   `0 <= Node.val <= 9`
 *   It is guaranteed that the list represents a number that does not have leading zeros.
 
+Here are the steps to solve the "Add Two Numbers" problem:
+
+### Approach:
+
+1. **Initialize Pointers and Carry:**
+   - Initialize three pointers, `p1` for the first linked list (`l1`), `p2` for the second linked list (`l2`), and `dummy_head` for the dummy node of the result linked list.
+   - Initialize `carry` to 0.
+
+2. **Traverse Both Linked Lists:**
+   - Traverse both linked lists until both pointers (`p1` and `p2`) reach the end.
+
+3. **Calculate Sum and Carry:**
+   - At each step, calculate the sum of the current digits and the carry from the previous step.
+   - Update `carry` for the next iteration.
+
+4. **Create New Node:**
+   - Create a new node with the value as the sum % 10 and add it to the result linked list.
+
+5. **Move Pointers:**
+   - Move both pointers (`p1` and `p2`) to the next nodes in their respective linked lists.
+
+6. **Handle Remaining Digits:**
+   - After both linked lists are traversed, check if there is any remaining carry.
+   - If there is, create a new node with the value of the carry and add it to the result linked list.
+
+7. **Return Result:**
+   - Return the next node of `dummy_head` as the head of the result linked list.
+
+### Python Code:
+
+```python
+# Definition for singly-linked list.
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
+class Solution:
+    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
+        dummy_head = ListNode()
+        p1, p2, current = l1, l2, dummy_head
+        carry = 0
+
+        while p1 or p2:
+            # Get values and handle None cases
+            x = p1.val if p1 else 0
+            y = p2.val if p2 else 0
+
+            # Calculate sum and carry
+            _sum = x + y + carry
+            carry = _sum // 10
+
+            # Create new node with the sum % 10
+            current.next = ListNode(_sum % 10)
+            current = current.next
+
+            # Move pointers to the next nodes
+            if p1:
+                p1 = p1.next
+            if p2:
+                p2 = p2.next
+
+        # Handle remaining carry
+        if carry > 0:
+            current.next = ListNode(carry)
+
+        return dummy_head.next
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+l1 = ListNode(2, ListNode(4, ListNode(3)))
+l2 = ListNode(5, ListNode(6, ListNode(4)))
+result = solution.addTwoNumbers(l1, l2)
+# Output: [7, 0, 8]
+
+# Example 2:
+l1 = ListNode(0)
+l2 = ListNode(0)
+result = solution.addTwoNumbers(l1, l2)
+# Output: [0]
+
+# Example 3:
+l1 = ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9, ListNode(9)))))))
+l2 = ListNode(9, ListNode(9, ListNode(9, ListNode(9))))
+result = solution.addTwoNumbers(l1, l2)
+# Output: [8, 9, 9, 9, 0, 0, 0, 1]
+```
+
+This code defines a `ListNode` class for the singly-linked list and a `Solution` class with a method `addTwoNumbers` that takes two linked lists as input and returns the result as a linked list. The example usage demonstrates how to create instances of the `ListNode` class and call the `addTwoNumbers` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0003_longest_substring_without_repeating_characters/readme.md b/src/main/python/g0001_0100/s0003_longest_substring_without_repeating_characters/readme.md
index b6336af..1cc659a 100644
--- a/src/main/python/g0001_0100/s0003_longest_substring_without_repeating_characters/readme.md
+++ b/src/main/python/g0001_0100/s0003_longest_substring_without_repeating_characters/readme.md
@@ -42,6 +42,86 @@ Given a string `s`, find the length of the **longest substring** without repeati
 *   <code>0 <= s.length <= 5 * 10<sup>4</sup></code>
 *   `s` consists of English letters, digits, symbols and spaces.
 
+Here are the steps to solve the "Longest Substring Without Repeating Characters" problem:
+
+### Approach:
+
+1. **Initialize Pointers and Variables:**
+   - Initialize two pointers, `start` and `end`, to define the current substring.
+   - Initialize a dictionary `char_index` to store the last index of each character in the substring.
+   - Initialize the variable `max_length` to track the length of the longest substring.
+
+2. **Traverse the String:**
+   - Use the `end` pointer to traverse through the string `s`.
+
+3. **Check for Repeating Characters:**
+   - If the character at the current `end` pointer is not in the substring (not in `char_index`), add it to the substring.
+   - Update `max_length` if the length of the current substring is greater than the previous maximum.
+
+4. **Adjust Start Pointer:**
+   - If the character is already in the substring, move the `start` pointer to the right of the last occurrence of that character.
+   - This ensures that the substring does not contain repeating characters.
+
+5. **Update Character Index:**
+   - Update the index of the current character in the `char_index` dictionary.
+
+6. **Repeat Until End of String:**
+   - Repeat steps 3-5 until the `end` pointer reaches the end of the string.
+
+7. **Return Maximum Length:**
+   - The maximum length of the substring without repeating characters is stored in the variable `max_length`.
+
+### Python Code:
+
+```python
+class Solution:
+    def lengthOfLongestSubstring(self, s: str) -> int:
+        # Initialize pointers and variables
+        start, end = 0, 0
+        char_index = {}  # Dictionary to store the last index of each character
+        max_length = 0
+
+        # Traverse the string
+        while end < len(s):
+            # Check for repeating characters
+            if s[end] not in char_index or char_index[s[end]] < start:
+                # Update max_length
+                max_length = max(max_length, end - start + 1)
+            else:
+                # Adjust start pointer
+                start = char_index[s[end]] + 1
+
+            # Update character index
+            char_index[s[end]] = end
+
+            # Move end pointer to the next character
+            end += 1
+
+        # Return the maximum length of the substring
+        return max_length
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+s1 = "abcabcbb"
+gprint(solution.lengthOfLongestSubstring(s1))  # Output: 3
+
+# Example 2:
+s2 = "bbbbb"
+print(solution.lengthOfLongestSubstring(s2))  # Output: 1
+
+# Example 3:
+s3 = "pwwkew"
+print(solution.lengthOfLongestSubstring(s3))  # Output: 3
+
+# Example 4:
+s4 = ""
+print(solution.lengthOfLongestSubstring(s4))  # Output: 0
+```
+
+This code defines a `Solution` class with a method `lengthOfLongestSubstring` that takes a string `s` as input and returns the length of the longest substring without repeating characters. The example usage demonstrates how to create an instance of the `Solution` class and call the `lengthOfLongestSubstring` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0004_median_of_two_sorted_arrays/readme.md b/src/main/python/g0001_0100/s0004_median_of_two_sorted_arrays/readme.md
index 8ecf2f2..ff70f23 100644
--- a/src/main/python/g0001_0100/s0004_median_of_two_sorted_arrays/readme.md
+++ b/src/main/python/g0001_0100/s0004_median_of_two_sorted_arrays/readme.md
@@ -52,6 +52,72 @@ The overall run time complexity should be `O(log (m+n))`.
 *   `1 <= m + n <= 2000`
 *   <code>-10<sup>6</sup> <= nums1[i], nums2[i] <= 10<sup>6</sup></code>
 
+Here are the steps to solve the "Median of Two Sorted Arrays" problem:
+
+### Approach:
+
+1. **Combine Arrays:**
+   - Combine the two sorted arrays (`nums1` and `nums2`) into a single sorted array (`merged`).
+   - This can be done by merging the arrays while maintaining the sorted order.
+
+2. **Find Median:**
+   - If the length of the combined array is odd, the median is the middle element.
+   - If the length is even, the median is the average of the two middle elements.
+
+3. **Handle Empty Arrays:**
+   - If one of the arrays is empty, find the median of the non-empty array.
+   - If both arrays are empty, return 0.
+
+### Python Code:
+
+```python
+class Solution:
+    def findMedianSortedArrays(self, nums1, nums2):
+        # Combine arrays
+        merged = sorted(nums1 + nums2)
+
+        # Find median
+        length = len(merged)
+        if length % 2 == 1:
+            # Odd length
+            return float(merged[length // 2])
+        else:
+            # Even length
+            mid1 = merged[length // 2 - 1]
+            mid2 = merged[length // 2]
+            return (mid1 + mid2) / 2.0
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+nums1_1 = [1, 3]
+nums2_1 = [2]
+print(solution.findMedianSortedArrays(nums1_1, nums2_1))  # Output: 2.00000
+
+# Example 2:
+nums1_2 = [1, 2]
+nums2_2 = [3, 4]
+print(solution.findMedianSortedArrays(nums1_2, nums2_2))  # Output: 2.50000
+
+# Example 3:
+nums1_3 = [0, 0]
+nums2_3 = [0, 0]
+print(solution.findMedianSortedArrays(nums1_3, nums2_3))  # Output: 0.00000
+
+# Example 4:
+nums1_4 = []
+nums2_4 = [1]
+print(solution.findMedianSortedArrays(nums1_4, nums2_4))  # Output: 1.00000
+
+# Example 5:
+nums1_5 = [2]
+nums2_5 = []
+print(solution.findMedianSortedArrays(nums1_5, nums2_5))  # Output: 2.00000
+```
+
+This code defines a `Solution` class with a method `findMedianSortedArrays` that takes two sorted arrays (`nums1` and `nums2`) as input and returns the median of the combined sorted array. The example usage demonstrates how to create an instance of the `Solution` class and call the `findMedianSortedArrays` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0005_longest_palindromic_substring/readme.md b/src/main/python/g0001_0100/s0005_longest_palindromic_substring/readme.md
index 5f1948a..ee75bd7 100644
--- a/src/main/python/g0001_0100/s0005_longest_palindromic_substring/readme.md
+++ b/src/main/python/g0001_0100/s0005_longest_palindromic_substring/readme.md
@@ -36,6 +36,89 @@ Given a string `s`, return _the longest palindromic substring_ in `s`.
 *   `1 <= s.length <= 1000`
 *   `s` consist of only digits and English letters.
 
+Here are the steps to solve the "Longest Palindromic Substring" problem:
+
+### Approach:
+
+1. **Initialize Variables:**
+   - Initialize two pointers, `start` and `end`, to represent the current substring being considered.
+   - Initialize a variable `max_length` to store the length of the longest palindromic substring found.
+   - Initialize variables `max_start` and `max_end` to store the starting and ending indices of the longest palindromic substring.
+
+2. **Expand Around Center:**
+   - Iterate through each character in the string `s`.
+   - For each character, consider it as the center of a potential palindrome and expand around it to find the longest palindrome.
+
+3. **Handle Odd-Length Palindromes:**
+   - For each character, expand the substring by considering the current character as the center and expanding outward on both sides.
+   - Update `start` and `end` pointers accordingly.
+
+4. **Handle Even-Length Palindromes:**
+   - Consider each pair of adjacent characters as potential centers and expand around them to find even-length palindromes.
+   - Update `start` and `end` pointers accordingly.
+
+5. **Update Longest Palindrome:**
+   - After expanding around the current center, check if the length of the palindrome is greater than the current maximum (`max_length`).
+   - If yes, update `max_length`, `max_start`, and `max_end`.
+
+6. **Return Result:**
+   - After iterating through all characters, return the longest palindromic substring using the indices `max_start` and `max_end`.
+
+### Python Code:
+
+```python
+class Solution:
+    def longestPalindrome(self, s: str) -> str:
+        # Initialize variables
+        max_length = 0
+        max_start, max_end = 0, 0
+
+        # Expand around center
+        for i in range(len(s)):
+            # Handle odd-length palindromes
+            start, end = self.expand_around_center(s, i, i)
+            if end - start + 1 > max_length:
+                max_length = end - start + 1
+                max_start, max_end = start, end
+
+            # Handle even-length palindromes
+            start, end = self.expand_around_center(s, i, i + 1)
+            if end - start + 1 > max_length:
+                max_length = end - start + 1
+                max_start, max_end = start, end
+
+        # Return the longest palindromic substring
+        return s[max_start:max_end + 1]
+
+    def expand_around_center(self, s, left, right):
+        # Expand around center and return indices of the palindrome
+        while left >= 0 and right < len(s) and s[left] == s[right]:
+            left -= 1
+            right += 1
+        return left + 1, right - 1
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+s1 = "babad"
+print(solution.longestPalindrome(s1))  # Output: "bab" or "aba"
+
+# Example 2:
+s2 = "cbbd"
+print(solution.longestPalindrome(s2))  # Output: "bb"
+
+# Example 3:
+s3 = "a"
+print(solution.longestPalindrome(s3))  # Output: "a"
+
+# Example 4:
+s4 = "ac"
+print(solution.longestPalindrome(s4))  # Output: "a"
+```
+
+This code defines a `Solution` class with a method `longestPalindrome` that takes a string `s` as input and returns the longest palindromic substring. The example usage demonstrates how to create an instance of the `Solution` class and call the `longestPalindrome` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0006_zigzag_conversion/readme.md b/src/main/python/g0001_0100/s0006_zigzag_conversion/readme.md
index d68463a..559b216 100644
--- a/src/main/python/g0001_0100/s0006_zigzag_conversion/readme.md
+++ b/src/main/python/g0001_0100/s0006_zigzag_conversion/readme.md
@@ -41,6 +41,85 @@ string convert(string s, int numRows);
 *   `s` consists of English letters (lower-case and upper-case), `','` and `'.'`.
 *   `1 <= numRows <= 1000`
 
+Here are the steps to solve the "Zigzag Conversion" problem:
+
+### Approach:
+
+1. **Handle Special Cases:**
+   - If the number of rows (`numRows`) is 1 or the length of the string (`s`) is less than or equal to the number of rows, return the original string.
+
+2. **Initialize Rows:**
+   - Create a list of strings to represent each row of the zigzag pattern.
+   - Initialize an index variable to keep track of the current row.
+
+3. **Iterate through the String:**
+   - Iterate through each character in the string `s`.
+
+4. **Fill Rows:**
+   - For each character, determine the current row in the zigzag pattern.
+   - Append the character to the corresponding row.
+
+5. **Read Zigzag Pattern:**
+   - Concatenate the rows to obtain the final zigzag pattern.
+
+6. **Return Result:**
+   - Return the final zigzag pattern.
+
+### Python Code:
+
+```python
+class Solution:
+    def convert(self, s: str, numRows: int) -> str:
+        # Handle special cases
+        if numRows == 1 or len(s) <= numRows:
+            return s
+
+        # Initialize rows
+        rows = [''] * numRows
+        index = 0
+        direction = 1  # 1 for down, -1 for up
+
+        # Iterate through the string
+        for char in s:
+            # Fill rows
+            rows[index] += char
+
+            # Change direction if reaching top or bottom row
+            if index == 0:
+                direction = 1
+            elif index == numRows - 1:
+                direction = -1
+
+            # Move to the next row
+            index += direction
+
+        # Read zigzag pattern
+        result = ''.join(rows)
+
+        # Return the final result
+        return result
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+s1 = "PAYPALISHIRING"
+numRows1 = 3
+print(solution.convert(s1, numRows1))  # Output: "PAHNAPLSIIGYIR"
+
+# Example 2:
+s2 = "PAYPALISHIRING"
+numRows2 = 4
+print(solution.convert(s2, numRows2))  # Output: "PINALSIGYAHRPI"
+
+# Example 3:
+s3 = "A"
+numRows3 = 1
+print(solution.convert(s3, numRows3))  # Output: "A"
+```
+
+This code defines a `Solution` class with a method `convert` that takes a string `s` and the number of rows `numRows` as input and returns the zigzag conversion of the string. The example usage demonstrates how to create an instance of the `Solution` class and call the `convert` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0007_reverse_integer/readme.md b/src/main/python/g0001_0100/s0007_reverse_integer/readme.md
index 0c659c9..0a58d29 100644
--- a/src/main/python/g0001_0100/s0007_reverse_integer/readme.md
+++ b/src/main/python/g0001_0100/s0007_reverse_integer/readme.md
@@ -37,6 +37,95 @@ Given a signed 32-bit integer `x`, return `x` _with its digits reversed_. If rev
 
 *   <code>-2<sup>31</sup> <= x <= 2<sup>31</sup> - 1</code>
 
+Here are the steps to solve the "Reverse Integer" problem:
+
+### Approach:
+
+1. **Handle Special Case for 0:**
+   - If the given integer `x` is 0, return 0.
+
+2. **Determine Sign:**
+   - Determine the sign of the integer `x` (positive or negative).
+
+3. **Handle Negative Case:**
+   - If `x` is negative, update the sign and make `x` positive for the reversal process.
+
+4. **Reverse the Digits:**
+   - Convert the positive `x` to a string.
+   - Reverse the string.
+
+5. **Handle Leading Zeros:**
+   - Remove leading zeros from the reversed string.
+
+6. **Convert Back to Integer:**
+   - Convert the reversed string back to an integer.
+
+7. **Apply Sign:**
+   - If the original `x` was negative, apply the negative sign to the reversed integer.
+
+8. **Check for Overflow:**
+   - Check if the reversed integer is within the 32-bit integer range <code>[-2<sup>31</sup>, 2<sup>31</sup> - 1]</code>.
+   - If not, return 0.
+
+9. **Return Result:**
+   - Return the reversed integer.
+
+### Python Code:
+
+```python
+class Solution:
+    def reverse(self, x: int) -> int:
+        # Handle special case for 0
+        if x == 0:
+            return 0
+
+        # Determine sign
+        sign = 1 if x > 0 else -1
+
+        # Make x positive for the reversal process
+        x = abs(x)
+
+        # Reverse the digits
+        reversed_str = str(x)[::-1]
+
+        # Remove leading zeros
+        reversed_str = reversed_str.lstrip('0')
+
+        # Convert back to integer
+        reversed_int = int(reversed_str)
+
+        # Apply sign
+        reversed_int *= sign
+
+        # Check for overflow
+        if reversed_int < -2**31 or reversed_int > 2**31 - 1:
+            return 0
+
+        # Return the reversed integer
+        return reversed_int
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+x1 = 123
+print(solution.reverse(x1))  # Output: 321
+
+# Example 2:
+x2 = -123
+print(solution.reverse(x2))  # Output: -321
+
+# Example 3:
+x3 = 120
+print(solution.reverse(x3))  # Output: 21
+
+# Example 4:
+x4 = 0
+print(solution.reverse(x4))  # Output: 0
+```
+
+This code defines a `Solution` class with a method `reverse` that takes an integer `x` as input and returns the reversed integer. The example usage demonstrates how to create an instance of the `Solution` class and call the `reverse` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0008_string_to_integer_atoi/readme.md b/src/main/python/g0001_0100/s0008_string_to_integer_atoi/readme.md
index a09bda8..e381a2c 100644
--- a/src/main/python/g0001_0100/s0008_string_to_integer_atoi/readme.md
+++ b/src/main/python/g0001_0100/s0008_string_to_integer_atoi/readme.md
@@ -115,6 +115,99 @@ Since -91283472332 is less than the lower bound of the range [-2<sup>31</sup>, 2
 *   `0 <= s.length <= 200`
 *   `s` consists of English letters (lower-case and upper-case), digits (`0-9`), `' '`, `'+'`, `'-'`, and `'.'`.
 
+Here are the steps to solve the "String to Integer (atoi)" problem:
+
+### Approach:
+
+1. **Handle Special Case for Empty String:**
+   - If the input string `s` is empty, return 0.
+
+2. **Skip Leading Whitespace:**
+   - Iterate through the string to skip any leading whitespace characters.
+
+3. **Determine Sign:**
+   - Check if the next character (if not already at the end of the string) is `'-'` or `'+'`. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present.
+
+4. **Read Digits:**
+   - Read in the characters until the next non-digit character or the end of the input is reached. The rest of the string is ignored.
+
+5. **Convert to Integer:**
+   - Convert the read digits into an integer.
+   - If no digits were read, return 0.
+
+6. **Apply Sign:**
+   - Change the sign of the integer as necessary based on the step 3.
+
+7. **Check for Overflow:**
+   - If the integer is out of the 32-bit signed integer range <code>[-2<sup>31</sup>, 2<sup>31</sup> - 1]</code>, then clamp the integer so that it remains in the range. Specifically, integers less than <code>-2<sup>31</sup></code> should be clamped to <code>-2<sup>31</sup></code>, and integers greater than <code>2<sup>31</sup> - 1</code> should be clamped to <code>2<sup>31</sup> - 1</code>.
+
+8. **Return Result:**
+   - Return the integer as the final result.
+
+### Python Code:
+
+```python
+class Solution:
+    def myAtoi(self, s: str) -> int:
+        # Handle special case for empty string
+        if not s:
+            return 0
+
+        # Skip leading whitespace
+        i = 0
+        while i < len(s) and s[i].isspace():
+            i += 1
+
+        # Determine sign
+        sign = 1
+        if i < len(s) and (s[i] == '-' or s[i] == '+'):
+            sign = -1 if s[i] == '-' else 1
+            i += 1
+
+        # Read digits
+        digits = 0
+        while i < len(s) and s[i].isdigit():
+            digits = digits * 10 + int(s[i])
+            i += 1
+
+        # Apply sign
+        result = sign * digits
+
+        # Check for overflow
+        INT_MIN, INT_MAX = -2**31, 2**31 - 1
+        if result < INT_MIN:
+            return INT_MIN
+        elif result > INT_MAX:
+            return INT_MAX
+        else:
+            return result
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+s1 = "42"
+print(solution.myAtoi(s1))  # Output: 42
+
+# Example 2:
+s2 = " -42"
+print(solution.myAtoi(s2))  # Output: -42
+
+# Example 3:
+s3 = "4193 with words"
+print(solution.myAtoi(s3))  # Output: 4193
+
+# Example 4:
+s4 = "words and 987"
+print(solution.myAtoi(s4))  # Output: 0
+
+# Example 5:
+s5 = "-91283472332"
+print(solution.myAtoi(s5))  # Output: -2147483648
+```
+
+This code defines a `Solution` class with a method `myAtoi` that takes a string `s` as input and returns the 32-bit signed integer. The example usage demonstrates how to create an instance of the `Solution` class and call the `myAtoi` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0009_palindrome_number/readme.md b/src/main/python/g0001_0100/s0009_palindrome_number/readme.md
index ce8ef8d..eb938c9 100644
--- a/src/main/python/g0001_0100/s0009_palindrome_number/readme.md
+++ b/src/main/python/g0001_0100/s0009_palindrome_number/readme.md
@@ -43,6 +43,68 @@ An integer is a **palindrome** when it reads the same backward as forward. For e
 
 **Follow up:** Could you solve it without converting the integer to a string?
 
+Here are the steps to solve the "Palindrome Number" problem:
+
+### Approach:
+
+1. **Handle Special Cases for Negative Numbers:**
+   - If the given integer `x` is negative, return `false` since negative numbers cannot be palindromes.
+
+2. **Reverse the Integer:**
+   - Reverse the digits of the positive integer `x` to obtain a new integer.
+
+3. **Check for Palindrome:**
+   - Compare the reversed integer with the original integer `x`.
+   - If they are equal, return `true`; otherwise, return `false`.
+
+4. **Return Result:**
+   - Return the result indicating whether the integer is a palindrome or not.
+
+### Python Code:
+
+```python
+class Solution:
+    def isPalindrome(self, x: int) -> bool:
+        # Handle special case for negative numbers
+        if x < 0:
+            return False
+
+        # Reverse the digits of the positive integer
+        reversed_x = self.reverse(x)
+
+        # Check for palindrome
+        return x == reversed_x
+
+    def reverse(self, x: int) -> int:
+        reversed_x = 0
+        while x > 0:
+            digit = x % 10
+            reversed_x = reversed_x * 10 + digit
+            x //= 10
+        return reversed_x
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+x1 = 121
+print(solution.isPalindrome(x1))  # Output: True
+
+# Example 2:
+x2 = -121
+print(solution.isPalindrome(x2))  # Output: False
+
+# Example 3:
+x3 = 10
+print(solution.isPalindrome(x3))  # Output: False
+
+# Example 4:
+x4 = -101
+print(solution.isPalindrome(x4))  # Output: False
+```
+
+This code defines a `Solution` class with a method `isPalindrome` that takes an integer `x` as input and returns `True` if it is a palindrome and `False` otherwise. The example usage demonstrates how to create an instance of the `Solution` class and call the `isPalindrome` method with different inputs. The `reverse` method is used to reverse the digits of a positive integer.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0010_regular_expression_matching/readme.md b/src/main/python/g0001_0100/s0010_regular_expression_matching/readme.md
index 6b88f99..0ba87fc 100644
--- a/src/main/python/g0001_0100/s0010_regular_expression_matching/readme.md
+++ b/src/main/python/g0001_0100/s0010_regular_expression_matching/readme.md
@@ -58,6 +58,69 @@ The matching should cover the **entire** input string (not partial).
 *   `p` contains only lowercase English letters, `'.'`, and `'*'`.
 *   It is guaranteed for each appearance of the character `'*'`, there will be a previous valid character to match.
 
+Here are the steps for the recursive approach:
+
+### Recursive Approach:
+
+1. **Base Cases:**
+   - If the pattern `p` is empty, the matching is successful if the string `s` is also empty. Return `True` if both are empty; otherwise, return `False`.
+   - If the pattern `p` has only one character or the next character is not `'*'`, check if the first characters of `s` and `p` match. If yes, move to the next characters of both `s` and `p`; otherwise, return `False`.
+
+2. **Handle '*' Character:**
+   - If the next character in `p` is `'*'`, there are two possibilities:
+     - Skip the `'*'` and the preceding character in `p` (i.e., match zero occurrences of the preceding character).
+     - Match one occurrence of the preceding character in `p` with the current character in `s`.
+
+3. **Recursive Calls:**
+   - Recursively call the function with updated `s` and `p` for the possibilities mentioned in step 2.
+
+4. **Return Result:**
+   - Return `True` if any recursive call returns `True`; otherwise, return `False`.
+
+### Python Code (Recursive):
+
+```python
+class Solution:
+    def isMatch(self, s: str, p: str) -> bool:
+        # Base cases
+        if not p:
+            return not s
+
+        first_match = bool(s) and (s[0] == p[0] or p[0] == '.')
+
+        # Handle '*' character
+        if len(p) >= 2 and p[1] == '*':
+            return (self.isMatch(s, p[2:]) or
+                    (first_match and self.isMatch(s[1:], p)))
+        else:
+            return first_match and self.isMatch(s[1:], p[1:])
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+s1, p1 = "aa", "a"
+print(solution.isMatch(s1, p1))  # Output: False
+
+# Example 2:
+s2, p2 = "aa", "a*"
+print(solution.isMatch(s2, p2))  # Output: True
+
+# Example 3:
+s3, p3 = "ab", ".*"
+print(solution.isMatch(s3, p3))  # Output: True
+
+# Example 4:
+s4, p4 = "aab", "c*a*b"
+print(solution.isMatch(s4, p4))  # Output: True
+
+# Example 5:
+s5, p5 = "mississippi", "mis*is*p*."
+print(solution.isMatch(s5, p5))  # Output: False
+```
+
+This code defines a `Solution` class with a method `isMatch` that takes a string `s` and a pattern `p` as input and returns `True` if they match and `False` otherwise. The example usage demonstrates how to create an instance of the `Solution` class and call the `isMatch` method with different inputs using the recursive approach.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0011_container_with_most_water/readme.md b/src/main/python/g0001_0100/s0011_container_with_most_water/readme.md
index bfa8287..3358cf4 100644
--- a/src/main/python/g0001_0100/s0011_container_with_most_water/readme.md
+++ b/src/main/python/g0001_0100/s0011_container_with_most_water/readme.md
@@ -43,6 +43,79 @@ Given `n` non-negative integers <code>a<sub>1</sub>, a<sub>2</sub>, ..., a<sub>n
 *   <code>2 <= n <= 10<sup>5</sup></code>
 *   <code>0 <= height[i] <= 10<sup>4</sup></code>
 
+Here are the steps to solve the "Container With Most Water" problem:
+
+### Approach:
+
+1. **Initialize Pointers:**
+   - Initialize two pointers, one at the beginning (`left`) and one at the end (`right`) of the height array.
+
+2. **Calculate Initial Area:**
+   - Calculate the initial area between the two pointers using the minimum height (`min_height`) and the width (`width`) between the pointers.
+
+3. **Move Pointers Inward:**
+   - Move the pointer with the smaller height towards the center of the array.
+     - If `height[left] < height[right]`, increment `left`.
+     - If `height[left] >= height[right]`, decrement `right`.
+
+4. **Update Maximum Area:**
+   - Update the maximum area if the newly calculated area is greater than the current maximum.
+
+5. **Repeat Until Pointers Meet:**
+   - Repeat steps 3-4 until the pointers meet.
+
+6. **Return Maximum Area:**
+   - Return the maximum area.
+
+### Python Code:
+
+```python
+class Solution:
+    def maxArea(self, height: List[int]) -> int:
+        # Initialize pointers
+        left, right = 0, len(height) - 1
+        max_area = 0
+
+        # Iterate until pointers meet
+        while left < right:
+            # Calculate width and minimum height
+            width = right - left
+            min_height = min(height[left], height[right])
+
+            # Update maximum area
+            max_area = max(max_area, width * min_height)
+
+            # Move pointers inward
+            if height[left] < height[right]:
+                left += 1
+            else:
+                right -= 1
+
+        # Return maximum area
+        return max_area
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+height1 = [1, 8, 6, 2, 5, 4, 8, 3, 7]
+print(solution.maxArea(height1))  # Output: 49
+
+# Example 2:
+height2 = [1, 1]
+print(solution.maxArea(height2))  # Output: 1
+
+# Example 3:
+height3 = [4, 3, 2, 1, 4]
+print(solution.maxArea(height3))  # Output: 16
+
+# Example 4:
+height4 = [1, 2, 1]
+print(solution.maxArea(height4))  # Output: 2
+```
+
+This code defines a `Solution` class with a method `maxArea` that takes an array of heights as input and returns the maximum area that can be formed by a container. The example usage demonstrates how to create an instance of the `Solution` class and call the `maxArea` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0015_3sum/readme.md b/src/main/python/g0001_0100/s0015_3sum/readme.md
index 1fc94b6..ba6d695 100644
--- a/src/main/python/g0001_0100/s0015_3sum/readme.md
+++ b/src/main/python/g0001_0100/s0015_3sum/readme.md
@@ -32,6 +32,97 @@ Notice that the solution set must not contain duplicate triplets.
 *   `0 <= nums.length <= 3000`
 *   <code>-10<sup>5</sup> <= nums[i] <= 10<sup>5</sup></code>
 
+Here are the steps to solve the "3Sum" problem:
+
+### Approach:
+
+1. **Sort the Array:**
+   - Sort the given array `nums` in ascending order.
+
+2. **Initialize Result List:**
+   - Initialize an empty list `result` to store the triplets.
+
+3. **Iterate Through the Array:**
+   - Iterate through the sorted array `nums` from index `i = 0` to `i = len(nums) - 3`.
+
+4. **Check for Duplicate Elements:**
+   - If the current element is the same as the previous element, skip to the next iteration to avoid duplicate triplets.
+
+5. **Use Two Pointers for 2Sum:**
+   - Use two pointers (`left` and `right`) to find a pair of elements whose sum is equal to the negation of the current element (`-nums[i]`).
+     - Initialize `left = i + 1` and `right = len(nums) - 1`.
+     - Check if `nums[i] + nums[left] + nums[right] == 0`.
+
+6. **Move Pointers:**
+   - If the sum is less than zero, increment `left`.
+   - If the sum is greater than zero, decrement `right`.
+   - If the sum is zero, add the triplet `[nums[i], nums[left], nums[right]]` to the result list.
+
+7. **Skip Duplicate Elements:**
+   - While moving pointers, skip duplicate elements to avoid duplicate triplets.
+
+8. **Return Result:**
+   - Return the final list of triplets.
+
+### Python Code:
+
+```python
+class Solution:
+    def threeSum(self, nums: List[int]) -> List[List[int]]:
+        # Sort the array
+        nums.sort()
+        result = []
+
+        # Iterate through the array
+        for i in range(len(nums) - 2):
+            # Check for duplicate elements
+            if i > 0 and nums[i] == nums[i - 1]:
+                continue
+
+            # Two pointers for 2Sum
+            left, right = i + 1, len(nums) - 1
+
+            while left < right:
+                total = nums[i] + nums[left] + nums[right]
+
+                if total < 0:
+                    left += 1
+                elif total > 0:
+                    right -= 1
+                else:
+                    # Add triplet to result
+                    result.append([nums[i], nums[left], nums[right]])
+
+                    # Skip duplicate elements
+                    while left < right and nums[left] == nums[left + 1]:
+                        left += 1
+                    while left < right and nums[right] == nums[right - 1]:
+                        right -= 1
+
+                    # Move pointers
+                    left += 1
+                    right -= 1
+
+        return result
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+nums1 = [-1, 0, 1, 2, -1, -4]
+print(solution.threeSum(nums1))  # Output: [[-1, -1, 2], [-1, 0, 1]]
+
+# Example 2:
+nums2 = []
+print(solution.threeSum(nums2))  # Output: []
+
+# Example 3:
+nums3 = [0]
+print(solution.threeSum(nums3))  # Output: []
+```
+
+This code defines a `Solution` class with a method `threeSum` that takes an array `nums` as input and returns a list of unique triplets whose sum is equal to zero. The example usage demonstrates how to create an instance of the `Solution` class and call the `threeSum` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0017_letter_combinations_of_a_phone_number/readme.md b/src/main/python/g0001_0100/s0017_letter_combinations_of_a_phone_number/readme.md
index bf13ee9..209244c 100644
--- a/src/main/python/g0001_0100/s0017_letter_combinations_of_a_phone_number/readme.md
+++ b/src/main/python/g0001_0100/s0017_letter_combinations_of_a_phone_number/readme.md
@@ -34,6 +34,90 @@ A mapping of digit to letters (just like on the telephone buttons) is given belo
 *   `0 <= digits.length <= 4`
 *   `digits[i]` is a digit in the range `['2', '9']`.
 
+Here are the steps to solve the "Letter Combinations of a Phone Number" problem:
+
+### Approach:
+
+1. **Define Letter Mapping:**
+   - Define a dictionary mapping each digit to its corresponding letters on the telephone keypad.
+
+2. **Initialize Result List:**
+   - Initialize an empty list `result` to store the letter combinations.
+
+3. **Check for Empty Input:**
+   - If the input string `digits` is empty, return an empty list.
+
+4. **Recursive Backtracking:**
+   - Use a recursive backtracking approach to generate all possible combinations.
+     - Define a recursive function that takes the current combination, current index, and the result list as parameters.
+     - Base case: If the current combination length is equal to the length of the input `digits`, add it to the result list.
+     - For the current digit, get its corresponding letters and recursively call the function for each letter with an updated combination and index.
+
+5. **Return Result List:**
+   - Return the final list of letter combinations.
+
+### Python Code:
+
+```python
+class Solution:
+    def letterCombinations(self, digits: str) -> List[str]:
+        # Define letter mapping
+        letter_mapping = {
+            '2': 'abc',
+            '3': 'def',
+            '4': 'ghi',
+            '5': 'jkl',
+            '6': 'mno',
+            '7': 'pqrs',
+            '8': 'tuv',
+            '9': 'wxyz'
+        }
+
+        # Initialize result list
+        result = []
+
+        # Base case: empty input
+        if not digits:
+            return result
+
+        # Recursive backtracking function
+        def backtrack(combination, index):
+            # Base case: combination length equals digits length
+            if index == len(digits):
+                result.append(''.join(combination))
+                return
+
+            # Get letters for current digit
+            current_digit = digits[index]
+            for letter in letter_mapping[current_digit]:
+                # Recursively call with updated combination and index
+                combination.append(letter)
+                backtrack(combination, index + 1)
+                combination.pop()
+
+        # Start recursive backtracking
+        backtrack([], 0)
+
+        return result
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+digits1 = "23"
+print(solution.letterCombinations(digits1))  # Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
+
+# Example 2:
+digits2 = ""
+print(solution.letterCombinations(digits2))  # Output: []
+
+# Example 3:
+digits3 = "2"
+print(solution.letterCombinations(digits3))  # Output: ["a","b","c"]
+```
+
+This code defines a `Solution` class with a method `letterCombinations` that takes a string of digits as input and returns a list of all possible letter combinations. The example usage demonstrates how to create an instance of the `Solution` class and call the `letterCombinations` method with different inputs.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0019_remove_nth_node_from_end_of_list/readme.md b/src/main/python/g0001_0100/s0019_remove_nth_node_from_end_of_list/readme.md
index 1f485b9..0e1516c 100644
--- a/src/main/python/g0001_0100/s0019_remove_nth_node_from_end_of_list/readme.md
+++ b/src/main/python/g0001_0100/s0019_remove_nth_node_from_end_of_list/readme.md
@@ -36,6 +36,81 @@ Given the `head` of a linked list, remove the `nth` node from the end of the lis
 
 **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.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0020_valid_parentheses/readme.md b/src/main/python/g0001_0100/s0020_valid_parentheses/readme.md
index 1fa364b..ff23110 100644
--- a/src/main/python/g0001_0100/s0020_valid_parentheses/readme.md
+++ b/src/main/python/g0001_0100/s0020_valid_parentheses/readme.md
@@ -47,6 +47,78 @@ An input string is valid if:
 *   <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.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0021_merge_two_sorted_lists/readme.md b/src/main/python/g0001_0100/s0021_merge_two_sorted_lists/readme.md
index 3a4afb1..f499459 100644
--- a/src/main/python/g0001_0100/s0021_merge_two_sorted_lists/readme.md
+++ b/src/main/python/g0001_0100/s0021_merge_two_sorted_lists/readme.md
@@ -33,6 +33,81 @@ Merge two sorted linked lists and return it as a **sorted** list. The list shoul
 *   `-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.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0022_generate_parentheses/readme.md b/src/main/python/g0001_0100/s0022_generate_parentheses/readme.md
index 9f2545e..a90f354 100644
--- a/src/main/python/g0001_0100/s0022_generate_parentheses/readme.md
+++ b/src/main/python/g0001_0100/s0022_generate_parentheses/readme.md
@@ -23,6 +23,69 @@ Given `n` pairs of parentheses, write a function to _generate all combinations o
 
 *   `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.
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0001_0100/s0023_merge_k_sorted_lists/readme.md b/src/main/python/g0001_0100/s0023_merge_k_sorted_lists/readme.md
index cbe96af..7aa1150 100644
--- a/src/main/python/g0001_0100/s0023_merge_k_sorted_lists/readme.md
+++ b/src/main/python/g0001_0100/s0023_merge_k_sorted_lists/readme.md
@@ -38,50 +38,74 @@ _Merge all the linked-lists into one sorted linked-list and return it._
 *   `lists[i]` is sorted in **ascending order**.
 *   The sum of `lists[i].length` won't exceed `10^4`.
 
-## Solution
+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
-# Definition for singly-linked list.
-# class ListNode:
-#     def __init__(self, val=0, next=None):
-#         self.val = val
-#         self.next = next
+import heapq
+
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
 class Solution:
-    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
-        if len(lists) == 0:
-            return ListNode().next
-        else:
-            cnt = 0
-            n = len(lists)
-
-            first = ListNode()
-            temp = first
-            while cnt < n:
-                temp.next = lists[cnt]
-                while temp.next is not None:
-                    temp = temp.next
-                cnt +=1
-            return self.list_to_linked_list(self.linked_list_to_list(first.next))
-
-    def linked_list_to_list(self,head):
-        if head == None:
-            return 
-        else:
-            l = []
-            temp = head
-            while temp is not None:
-                l.append(temp.val)
-                temp = temp.next
-            return sorted(l)
-
-    def list_to_linked_list(self,l):
-        if l == None:
-            return
-        first = ListNode()
-        temp = first
-        for i in l:
-            node = ListNode(i)
-            temp.next = node
-            temp = temp.next
-        return first.next
-```
\ No newline at end of file
+    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/src/main/python/g0001_0100/s0024_swap_nodes_in_pairs/readme.md b/src/main/python/g0001_0100/s0024_swap_nodes_in_pairs/readme.md
index 9a3ed52..55db1af 100644
--- a/src/main/python/g0001_0100/s0024_swap_nodes_in_pairs/readme.md
+++ b/src/main/python/g0001_0100/s0024_swap_nodes_in_pairs/readme.md
@@ -32,22 +32,74 @@ Given a linked list, swap every two adjacent nodes and return its head. You must
 *   The number of nodes in the list is in the range `[0, 100]`.
 *   `0 <= Node.val <= 100`
 
-## Solution
+To solve the "Swap Nodes in Pairs" problem, you can follow these steps:
 
-```python
-# Definition for singly-linked list.
-# class ListNode:
-#     def __init__(self, val=0, next=None):
-#         self.val = val
-#         self.next = next
-class Solution:
-    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
-        if head is None or head.next is None:  
-            return head  
-        nxt = head.next
+### 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.
 
-        head.next = self.swapPairs(nxt.next)  
-        nxt.next = head
+4. **Return Modified Head:**
+   - Return the `dummy.next` as the new head of the modified linked list.
 
-        return nxt
-```
\ No newline at end of file
+### 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/src/main/python/g0001_0100/s0025_reverse_nodes_in_k_group/readme.md b/src/main/python/g0001_0100/s0025_reverse_nodes_in_k_group/readme.md
index 67c7566..7c5fe99 100644
--- a/src/main/python/g0001_0100/s0025_reverse_nodes_in_k_group/readme.md
+++ b/src/main/python/g0001_0100/s0025_reverse_nodes_in_k_group/readme.md
@@ -48,43 +48,98 @@ You may not alter the values in the list's nodes, only nodes themselves may be c
 
 **Follow-up:** Can you solve the problem in O(1) extra memory space?
 
-## Solution
+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
-# Definition for singly-linked list.
-# class ListNode:
-#     def __init__(self, val=0, next=None):
-#         self.val = val
-#         self.next = next
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
 class Solution:
-    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
-        if head is None or head.next is None or k == 1:
-            return head
-
-        j = 0
-        length = head
-        # Loop for checking the length of the linked list, if the linked list is less than k, then return it as it is.
-        while j < k:
-            if length is None:
-                return head
-            length = length.next
-            j += 1
-
-        # Reverse linked list logic applied here.
-        current = head
-        next_node = None
-        prev = None
-        i = 0
-        # Traverse the while loop for k times to reverse the node in k groups.
-        while i != k:
-            next_node = current.next
-            current.next = prev
-            prev = current
-            current = next_node
-            i += 1
-
-        # 'head' is now pointing to the first node of k group, which is now going to point to the next k group linked list.
-        # Recursion for further remaining linked list.
-        head.next = self.reverseKGroup(current, k)
-        return prev
-```
\ No newline at end of file
+    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/src/main/python/g0001_0100/s0031_next_permutation/readme.md b/src/main/python/g0001_0100/s0031_next_permutation/readme.md
index 55a8e1c..8bb1fc2 100644
--- a/src/main/python/g0001_0100/s0031_next_permutation/readme.md
+++ b/src/main/python/g0001_0100/s0031_next_permutation/readme.md
@@ -40,35 +40,66 @@ The replacement must be **[in place](http://en.wikipedia.org/wiki/In-place_algor
 *   `1 <= nums.length <= 100`
 *   `0 <= nums[i] <= 100`
 
-## Solution
+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: List[int]) -> None:
-        """
-        Do not return anything, modify nums in-place instead.
-        """
-        if not nums or len(nums) <= 1:
-            return
-
+    def nextPermutation(self, nums):
+        # Step 1: Find the first decreasing element
         i = len(nums) - 2
-        while i >= 0 and nums[i] >= nums[i + 1]:
+        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
-            self.swap(nums, i, j)
 
-        self.reverse(nums, i + 1, len(nums) - 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]
 
-    def swap(self, nums, i, j):
-        nums[i], nums[j] = nums[j], nums[i]
+# Example 4:
+nums4 = [1]
+solution.nextPermutation(nums4)  # Output: [1]
+```
 
-    def reverse(self, nums, i, j):
-        while i < j:
-            self.swap(nums, i, j)
-            i += 1
-            j -= 1
-```
\ No newline at end of file
+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/src/main/python/g0001_0100/s0032_longest_valid_parentheses/readme.md b/src/main/python/g0001_0100/s0032_longest_valid_parentheses/readme.md
index 4506b9c..c939227 100644
--- a/src/main/python/g0001_0100/s0032_longest_valid_parentheses/readme.md
+++ b/src/main/python/g0001_0100/s0032_longest_valid_parentheses/readme.md
@@ -34,42 +34,61 @@ Given a string containing just the characters `'('` and `')'`, find the length o
 *   <code>0 <= s.length <= 3 * 10<sup>4</sup></code>
 *   `s[i]` is `'('`, or `')'`.
 
-## Solution
+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: str) -> int:
+    def longestValidParentheses(self, s):
+        stack = [-1]  # Initialize the stack with -1 to handle the case when the first parenthesis is ')'
         max_length = 0
-        left = 0
-        right = 0
-        n = len(s)
-        
-        # First pass: left to right
-        for i in range(n):
-            if s[i] == '(':
-                left += 1
-            else:
-                right += 1
-            if right > left:
-                left = 0
-                right = 0
-            if left == right:
-                max_length = max(max_length, 2 * right)
-        
-        left = 0
-        right = 0
-        
-        # Second pass: right to left
-        for i in range(n - 1, -1, -1):
+
+        for i in range(len(s)):
             if s[i] == '(':
-                left += 1
-            else:
-                right += 1
-            if left > right:
-                left = 0
-                right = 0
-            if left == right:
-                max_length = max(max_length, 2 * left)
-        
+                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
-```
\ No newline at end of file
+
+# 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/src/main/python/g0001_0100/s0033_search_in_rotated_sorted_array/readme.md b/src/main/python/g0001_0100/s0033_search_in_rotated_sorted_array/readme.md
index b3712fc..4a48f6e 100644
--- a/src/main/python/g0001_0100/s0033_search_in_rotated_sorted_array/readme.md
+++ b/src/main/python/g0001_0100/s0033_search_in_rotated_sorted_array/readme.md
@@ -39,29 +39,89 @@ You must write an algorithm with `O(log n)` runtime complexity.
 *   `nums` is an ascending array that is possibly rotated.
 *   <code>-10<sup>4</sup> <= target <= 10<sup>4</sup></code>
 
-## Solution
+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: List[int], target: int) -> int:
-        lo, hi = 0, len(nums) - 1
-        
-        while lo <= hi:
-            mid = (hi - lo) // 2 + lo
-            if nums[mid] == target:
-                return mid
-            # If the left half is sorted
-            if nums[lo] <= nums[mid]:
-                if nums[lo] <= target <= nums[mid]:
-                    hi = mid - 1
+    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:
-                    lo = mid + 1
-            # If the right half is sorted
-            else:
-                if nums[mid] <= target <= nums[hi]:
-                    lo = mid + 1
+                    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:
-                    hi = mid - 1
-        
-        return -1
-```
\ No newline at end of file
+                    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
diff --git a/src/main/python/g0001_0100/s0039_combination_sum/readme.md b/src/main/python/g0001_0100/s0039_combination_sum/readme.md
index a03f7ed..0f457a1 100644
--- a/src/main/python/g0001_0100/s0039_combination_sum/readme.md
+++ b/src/main/python/g0001_0100/s0039_combination_sum/readme.md
@@ -54,26 +54,54 @@ It is **guaranteed** that the number of unique combinations that sum up to `targ
 *   All elements of `candidates` are **distinct**.
 *   `1 <= target <= 500`
 
-## Solution
+To solve the Combination Sum problem, you can use backtracking. Here are the steps you can follow:
+
+1. **Define the function**: Create a function, let's name it `combinationSum`, that takes `candidates`, `target`, and any other necessary parameters.
+
+2. **Sort the candidates**: Sort the `candidates` array. Sorting helps in pruning the search space during backtracking.
+
+3. **Initialize variables**: Initialize an empty list to store the result combinations. 
+
+4. **Define a helper function**: Create a recursive helper function, let's name it `backtrack`, that takes the current combination, the current index of the candidate being considered, and the remaining target.
+
+5. **Base case**: If the target is 0, add the current combination to the result list.
+
+6. **Iterate through candidates**: Start iterating from the current index to the end of the `candidates` array.
+
+7. **Check the sum condition**: For each candidate, check if adding it to the current combination keeps the sum less than or equal to the target. If so, recursively call the `backtrack` function with the updated combination, the current index, and the reduced target.
+
+8. **Backtrack**: After the recursive call returns, remove the last element from the current combination to backtrack.
+
+9. **Call the helper function**: Call the `backtrack` function initially with an empty combination, starting index 0, and the target.
+
+10. **Return the result**: Return the list of combinations obtained.
+
+Here's a Python code snippet implementing the above steps:
 
 ```python
 class Solution:
-    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
-        ans = []
-        sub_list = []
-        self.combinationSumRec(len(candidates), candidates, target, sub_list, ans)
-        return ans
-
-    def combinationSumRec(self, n: int, coins: List[int], amount: int, sub_list: List[int], ans: List[List[int]]):
-        if amount == 0 or n == 0:
-            if amount == 0:
-                ans.append(sub_list.copy())
-            return
-        
-        if amount - coins[n - 1] >= 0:
-            sub_list.append(coins[n - 1])
-            self.combinationSumRec(n, coins, amount - coins[n - 1], sub_list, ans)
-            sub_list.pop()
-        
-        self.combinationSumRec(n - 1, coins, amount, sub_list, ans)
-```
\ No newline at end of file
+    def combinationSum(self, candidates, target):
+        def backtrack(start, target, path):
+            if target == 0:
+                result.append(path)
+                return
+            for i in range(start, len(candidates)):
+                if candidates[i] > target:
+                    break
+                backtrack(i, target - candidates[i], path + [candidates[i]])
+
+        result = []
+        candidates.sort()
+        backtrack(0, target, [])
+        return result
+
+# Test cases
+solution = Solution()
+print(solution.combinationSum([2,3,6,7], 7)) # Output: [[2, 2, 3], [7]]
+print(solution.combinationSum([2,3,5], 8))   # Output: [[2, 2, 2, 2], [2, 3, 3], [5, 3]]
+print(solution.combinationSum([2], 1))        # Output: []
+print(solution.combinationSum([1], 1))        # Output: [[1]]
+print(solution.combinationSum([1], 2))        # Output: [[1, 1]]
+```
+
+This implementation efficiently finds all unique combinations that sum up to the target.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0041_first_missing_positive/readme.md b/src/main/python/g0001_0100/s0041_first_missing_positive/readme.md
index ba09f8d..f91388b 100644
--- a/src/main/python/g0001_0100/s0041_first_missing_positive/readme.md
+++ b/src/main/python/g0001_0100/s0041_first_missing_positive/readme.md
@@ -32,15 +32,59 @@ You must implement an algorithm that runs in `O(n)` time and uses constant extra
 *   <code>1 <= nums.length <= 5 * 10<sup>5</sup></code>
 *   <code>-2<sup>31</sup> <= nums[i] <= 2<sup>31</sup> - 1</code>
 
-## Solution
+To solve the "First Missing Positive" problem efficiently with O(n) time complexity and constant extra space, you can use the cyclic sort algorithm. Here's a step-by-step approach:
+
+### Approach:
+
+1. **Cyclic Sort:**
+   - Perform cyclic sort on the given array `nums`.
+   - Iterate through each number in the array and place it in its correct position if it is a positive integer and within the range of the array size.
+   - Ignore negative numbers and numbers greater than the size of the array.
+   - After cyclic sort, the array should contain positive integers starting from 1 to n, where n is the size of the array.
+
+2. **Find the First Missing Positive:**
+   - Iterate through the sorted array.
+   - The first index where the value is not equal to its index plus one is the smallest missing positive integer.
+   - If all numbers are in their correct positions, the smallest missing positive integer is the next integer after the array size.
+
+### Python Code:
 
 ```python
 class Solution:
-    def firstMissingPositive(self, nums: List[int]) -> int:
-        counter = 1
-        nums = set(nums)
-        while True:
-            if counter not in nums:
-                return counter
-            counter += 1
-```
\ No newline at end of file
+    def firstMissingPositive(self, nums):
+        n = len(nums)
+        i = 0
+
+        while i < n:
+            # If the number is positive and within the range of the array size,
+            # and it's not already in its correct position, swap it to its correct position.
+            if 1 <= nums[i] <= n and nums[i] != nums[nums[i] - 1]:
+                nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
+            else:
+                i += 1
+
+        # Iterate through the sorted array to find the first missing positive integer.
+        for i in range(n):
+            if nums[i] != i + 1:
+                return i + 1
+
+        # If all numbers are in their correct positions, return the next positive integer.
+        return n + 1
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+nums1 = [1, 2, 0]
+print(solution.firstMissingPositive(nums1))  # Output: 3
+
+# Example 2:
+nums2 = [3, 4, -1, 1]
+print(solution.firstMissingPositive(nums2))  # Output: 2
+
+# Example 3:
+nums3 = [7, 8, 9, 11, 12]
+print(solution.firstMissingPositive(nums3))  # Output: 1
+```
+
+This code defines a `Solution` class with a `firstMissingPositive` method to find the smallest missing positive integer in the given unsorted array `nums`. The example usage demonstrates how to create an instance of the `Solution` class and call the `firstMissingPositive` method with different inputs.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0042_trapping_rain_water/readme.md b/src/main/python/g0001_0100/s0042_trapping_rain_water/readme.md
index 3a20c00..c4d8aff 100644
--- a/src/main/python/g0001_0100/s0042_trapping_rain_water/readme.md
+++ b/src/main/python/g0001_0100/s0042_trapping_rain_water/readme.md
@@ -29,25 +29,63 @@ Given `n` non-negative integers representing an elevation map where the width of
 *   <code>1 <= n <= 2 * 10<sup>4</sup></code>
 *   <code>0 <= height[i] <= 10<sup>5</sup></code>
 
-## Solution
+To solve the "Trapping Rain Water" problem efficiently, you can use a two-pointer approach. Here are the steps to solve the problem:
+
+### Approach:
+
+1. **Initialize Pointers:**
+   - Initialize two pointers `left` and `right` at the two ends of the array `height`.
+
+2. **Initialize Variables:**
+   - Initialize variables `max_left` and `max_right` to keep track of the maximum height encountered from the left and right sides, respectively.
+   - Initialize a variable `water` to store the total trapped water.
+
+3. **Iterate Through Array:**
+   - While `left` pointer is less than `right` pointer, do the following:
+     - If `height[left]` is less than or equal to `height[right]`:
+       - Update `max_left` to the maximum of `max_left` and `height[left]`.
+       - Add `max_left - height[left]` to `water`.
+       - Increment `left` pointer.
+     - Else:
+       - Update `max_right` to the maximum of `max_right` and `height[right]`.
+       - Add `max_right - height[right]` to `water`.
+       - Decrement `right` pointer.
+
+4. **Return Result:**
+   - After the loop ends, return the total trapped water.
+
+### Python Code:
 
 ```python
 class Solution:
-    def trap(self, height: List[int]) -> int:
-        l, r = 0, len(height) - 1
-        res = 0
-        lower_wall = 0
+    def trap(self, height):
+        n = len(height)
+        left, right = 0, n - 1
+        max_left = max_right = 0
+        water = 0
         
-        while l < r:
-            l_val, r_val = height[l], height[r]
-            if l_val < r_val:
-                lower_wall = max(l_val, lower_wall)
-                res += lower_wall - l_val
-                l += 1
+        while left < right:
+            if height[left] <= height[right]:
+                max_left = max(max_left, height[left])
+                water += max_left - height[left]
+                left += 1
             else:
-                lower_wall = max(r_val, lower_wall)
-                res += lower_wall - r_val
-                r -= 1
-        
-        return res
-```
\ No newline at end of file
+                max_right = max(max_right, height[right])
+                water += max_right - height[right]
+                right -= 1
+                
+        return water
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+height1 = [0,1,0,2,1,0,1,3,2,1,2,1]
+print(solution.trap(height1))  # Output: 6
+
+# Example 2:
+height2 = [4,2,0,3,2,5]
+print(solution.trap(height2))  # Output: 9
+```
+
+This code defines a `Solution` class with a `trap` method to compute how much water can be trapped after raining in the given elevation map represented by the array `height`. The example usage demonstrates how to create an instance of the `Solution` class and call the `trap` method with different inputs.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0045_jump_game_ii/readme.md b/src/main/python/g0001_0100/s0045_jump_game_ii/readme.md
index 596c9fa..91883d0 100644
--- a/src/main/python/g0001_0100/s0045_jump_game_ii/readme.md
+++ b/src/main/python/g0001_0100/s0045_jump_game_ii/readme.md
@@ -32,24 +32,50 @@ You can assume that you can always reach the last index.
 *   <code>1 <= nums.length <= 10<sup>4</sup></code>
 *   `0 <= nums[i] <= 1000`
 
-## Solution
+To solve the "Jump Game II" problem efficiently, you can use a greedy approach. Here are the steps to solve the problem:
+
+### Approach:
+
+1. **Initialize Variables:**
+   - Initialize variables `max_reach` to store the farthest index that can be reached from the current position.
+   - Initialize variables `steps` to store the minimum number of jumps needed to reach the current position.
+   - Initialize variables `last_jump` to store the index where the last jump was made.
+
+2. **Iterate Through Array:**
+   - Iterate through the array `nums` up to the second last index.
+   - For each index `i`:
+     - Update `max_reach` to the maximum of `max_reach` and `i + nums[i]`.
+     - If `i` reaches the `last_jump` index, update `last_jump` to `max_reach` and increment `steps`.
+
+3. **Return Result:**
+   - After the loop ends, return the `steps` variable, which contains the minimum number of jumps needed to reach the last index.
+
+### Python Code:
 
 ```python
 class Solution:
-    def jump(self, nums: List[int]) -> int:
-        length = 0
-        max_length = 0
-        min_jump = 0
-        
-        for i in range(len(nums) - 1):
-            length -= 1
-            max_length -= 1
-            max_length = max(max_length, nums[i])
-            if length <= 0:
-                length = max_length
-                min_jump += 1
-            if length >= len(nums) - i - 1:
-                return min_jump
+    def jump(self, nums):
+        n = len(nums)
+        max_reach = last_jump = steps = 0
         
-        return min_jump
-```
\ No newline at end of file
+        for i in range(n - 1):
+            max_reach = max(max_reach, i + nums[i])
+            if i == last_jump:
+                last_jump = max_reach
+                steps += 1
+                
+        return steps
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+nums1 = [2,3,1,1,4]
+print(solution.jump(nums1))  # Output: 2
+
+# Example 2:
+nums2 = [2,3,0,1,4]
+print(solution.jump(nums2))  # Output: 2
+```
+
+This code defines a `Solution` class with a `jump` method to compute the minimum number of jumps needed to reach the last index in the given array `nums`. The example usage demonstrates how to create an instance of the `Solution` class and call the `jump` method with different inputs.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0046_permutations/readme.md b/src/main/python/g0001_0100/s0046_permutations/readme.md
index 6fa77ff..4df07f5 100644
--- a/src/main/python/g0001_0100/s0046_permutations/readme.md
+++ b/src/main/python/g0001_0100/s0046_permutations/readme.md
@@ -31,29 +31,65 @@ Given an array `nums` of distinct integers, return _all the possible permutation
 *   `-10 <= nums[i] <= 10`
 *   All the integers of `nums` are **unique**.
 
-## Solution
+To solve the "Permutations" problem, you can use backtracking. Here are the steps to solve the problem:
+
+### Approach:
+
+1. **Define Backtracking Function:**
+   - Define a backtracking function `backtrack` to generate permutations recursively.
+   - The function should take three parameters:
+     - `path`: The current permutation being generated.
+     - `nums`: The input array of distinct integers.
+     - `result`: A list to store all permutations.
+
+2. **Base Case:**
+   - If the length of `path` equals the length of `nums`, append a copy of `path` to `result` and return.
+
+3. **Recursive Step:**
+   - Iterate through each element `num` in `nums`.
+   - If `num` is not in `path`, append `num` to `path`.
+   - Recur with the updated `path`.
+
+4. **Generate Permutations:**
+   - Call the backtracking function `backtrack` with an empty list `path`, the input array `nums`, and an empty list `result`.
+
+5. **Return Result:**
+   - After generating all permutations, return the `result` list.
+
+### Python Code:
 
 ```python
 class Solution:
-    def permute(self, nums: List[int]) -> List[List[int]]:
-        if not nums:
-            return []
+    def permute(self, nums):
+        def backtrack(path, nums, result):
+            if len(path) == len(nums):
+                result.append(path[:])
+                return
+            
+            for num in nums:
+                if num not in path:
+                    path.append(num)
+                    backtrack(path, nums, result)
+                    path.pop()
         
-        final_result = []
-        self.permute_recur(nums, final_result, [], [False] * len(nums))
-        return final_result
-
-    def permute_recur(self, nums: List[int], final_result: List[List[int]], curr_result: List[int], used: List[bool]):
-        if len(curr_result) == len(nums):
-            final_result.append(curr_result.copy())
-            return
-        
-        for i in range(len(nums)):
-            if used[i]:
-                continue
-            curr_result.append(nums[i])
-            used[i] = True
-            self.permute_recur(nums, final_result, curr_result, used)
-            used[i] = False
-            curr_result.pop()
-```
\ No newline at end of file
+        result = []
+        backtrack([], nums, result)
+        return result
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+nums1 = [1,2,3]
+print(solution.permute(nums1))  # Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
+
+# Example 2:
+nums2 = [0,1]
+print(solution.permute(nums2))  # Output: [[0,1],[1,0]]
+
+# Example 3:
+nums3 = [1]
+print(solution.permute(nums3))  # Output: [[1]]
+```
+
+This code defines a `Solution` class with a `permute` method to generate all possible permutations of the given array `nums`. The example usage demonstrates how to create an instance of the `Solution` class and call the `permute` method with different inputs.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0048_rotate_image/readme.md b/src/main/python/g0001_0100/s0048_rotate_image/readme.md
index d73d748..64b4237 100644
--- a/src/main/python/g0001_0100/s0048_rotate_image/readme.md
+++ b/src/main/python/g0001_0100/s0048_rotate_image/readme.md
@@ -44,27 +44,66 @@ You have to rotate the image [**in-place**](https://en.wikipedia.org/wiki/In-pla
 *   `1 <= n <= 20`
 *   `-1000 <= matrix[i][j] <= 1000`
 
-## Solution
+To solve the "Rotate Image" problem, you can perform the rotation in-place by swapping elements of the matrix. Here are the steps to solve the problem:
+
+### Approach:
+
+1. **Transpose the Matrix:**
+   - Transpose the matrix by swapping `matrix[i][j]` with `matrix[j][i]` for all `i` and `j` where `i < j`.
+
+2. **Reverse Each Row:**
+   - Reverse each row of the transposed matrix to get the final rotated matrix.
+
+### Python Code:
 
 ```python
 class Solution:
-    def rotate(self, matrix: List[List[int]]) -> None:
-        """
-        Do not return anything, modify matrix in-place instead.
-        """
+    def rotate(self, matrix):
         n = len(matrix)
-        for i in range(n // 2):
-            for j in range(i, n - i - 1):
-                positions = [
-                    [i, j],
-                    [j, n - 1 - i],
-                    [n - 1 - i, n - 1 - j],
-                    [n - 1 - j, i]
-                ]
-                t = matrix[positions[0][0]][positions[0][1]]
-                for k in range(1, len(positions)):
-                    temp = matrix[positions[k][0]][positions[k][1]]
-                    matrix[positions[k][0]][positions[k][1]] = t
-                    t = temp
-                matrix[positions[0][0]][positions[0][1]] = t
-```
\ No newline at end of file
+        
+        # Transpose the matrix
+        for i in range(n):
+            for j in range(i + 1, n):
+                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
+        
+        # Reverse each row
+        for i in range(n):
+            matrix[i] = matrix[i][::-1]
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+matrix1 = [
+    [1,2,3],
+    [4,5,6],
+    [7,8,9]
+]
+solution.rotate(matrix1)
+print(matrix1)  # Output: [[7,4,1],[8,5,2],[9,6,3]]
+
+# Example 2:
+matrix2 = [
+    [5,1,9,11],
+    [2,4,8,10],
+    [13,3,6,7],
+    [15,14,12,16]
+]
+solution.rotate(matrix2)
+print(matrix2)  # Output: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
+
+# Example 3:
+matrix3 = \[\[1]]
+solution.rotate(matrix3)
+print(matrix3)  # Output: [[1]]
+
+# Example 4:
+matrix4 = [
+    [1,2],
+    [3,4]
+]
+solution.rotate(matrix4)
+print(matrix4)  # Output: [[3,1],[4,2]]
+```
+
+This code defines a `Solution` class with a `rotate` method to rotate the given matrix by 90 degrees clockwise. The example usage demonstrates how to create an instance of the `Solution` class and call the `rotate` method with different input matrices.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0049_group_anagrams/readme.md b/src/main/python/g0001_0100/s0049_group_anagrams/readme.md
index ed601b0..424ee98 100644
--- a/src/main/python/g0001_0100/s0049_group_anagrams/readme.md
+++ b/src/main/python/g0001_0100/s0049_group_anagrams/readme.md
@@ -33,16 +33,57 @@ An **Anagram** is a word or phrase formed by rearranging the letters of a differ
 *   `0 <= strs[i].length <= 100`
 *   `strs[i]` consists of lowercase English letters.
 
-## Solution
+To solve the "Group Anagrams" problem, you can use a hash table to group the anagrams together based on their sorted representations. Here are the steps to solve the problem:
+
+### Approach:
+
+1. **Initialize a Hash Table:**
+   - Initialize an empty dictionary to store the groups of anagrams. The keys of the dictionary will be the sorted representations of the words, and the values will be lists containing the original words.
+
+2. **Iterate Through the Strings:**
+   - Iterate through each string in the given array `strs`.
+
+3. **Sort Each String:**
+   - For each string, sort its characters alphabetically to get its sorted representation.
+
+4. **Group Anagrams:**
+   - Use the sorted representation as the key in the dictionary and append the original word to the corresponding list in the dictionary.
+
+5. **Return the Groups:**
+   - Return the values of the dictionary, which contain the groups of anagrams.
+
+### Python Code:
 
 ```python
 from collections import defaultdict
 
 class Solution:
-    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
-        anagram_groups = defaultdict(list)
-        for s in strs:
-            sorted_str = ''.join(sorted(s))
-            anagram_groups[sorted_str].append(s)
-        return list(anagram_groups.values())
-```
\ No newline at end of file
+    def groupAnagrams(self, strs):
+        # Initialize a dictionary to store groups of anagrams
+        groups = defaultdict(list)
+        
+        # Group anagrams based on their sorted representations
+        for word in strs:
+            sorted_word = ''.join(sorted(word))
+            groups[sorted_word].append(word)
+        
+        # Return the groups of anagrams
+        return list(groups.values())
+
+# Example Usage:
+solution = Solution()
+
+# Example 1:
+strs1 = ["eat","tea","tan","ate","nat","bat"]
+print(solution.groupAnagrams(strs1))  # Output: [["eat","tea","ate"],["tan","nat"],["bat"]]
+
+# Example 2:
+strs2 = [""]
+print(solution.groupAnagrams(strs2))  # Output: [[""]]
+
+# Example 3:
+strs3 = ["a"]
+print(solution.groupAnagrams(strs3))  # Output: [["a"]]
+```
+
+This code defines a `Solution` class with a `groupAnagrams` method to group the anagrams together. The example usage demonstrates how to create an instance of the `Solution` class and call the `groupAnagrams` method with different input arrays of strings.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0051_n_queens/readme.md b/src/main/python/g0001_0100/s0051_n_queens/readme.md
index 48421dc..e72c3ed 100644
--- a/src/main/python/g0001_0100/s0051_n_queens/readme.md
+++ b/src/main/python/g0001_0100/s0051_n_queens/readme.md
@@ -31,39 +31,72 @@ Each solution contains a distinct board configuration of the n-queens' placement
 
 *   `1 <= n <= 9`
 
-## Solution
+To solve the N-Queens problem, which involves placing N queens on an N x N chessboard without attacking each other, you can use backtracking. Here are the steps to solve the problem:
+
+### Approach:
+
+1. **Initialize the Chessboard:**
+   - Initialize an empty N x N chessboard grid.
+
+2. **Backtracking Function:**
+   - Define a backtracking function to recursively explore all possible queen placements.
+
+3. **Base Case:**
+   - If all queens are placed (i.e., row index equals N), add the current configuration to the list of solutions.
+
+4. **Try Placing Queen:**
+   - For the current row, try placing the queen in each column (0 to N-1).
+   - If placing the queen at the current position is safe (i.e., not attacking any other queen), mark the cell as a queen ('Q') and recursively move to the next row.
+
+5. **Backtrack:**
+   - After exploring all possibilities from the current position, backtrack by removing the queen from the current position and try the next column.
+
+6. **Return Solutions:**
+   - Return the list of all distinct solutions found.
+
+### Python Code:
 
 ```python
 class Solution:
-    def solveNQueens(self, n: int) -> List[List[str]]:
-        pos = [False] * (n + 2 * n - 1 + 2 * n - 1)
-        pos2 = [0] * n
-        ans = []
-        self.helper(n, 0, pos, pos2, ans)
-        return ans
-
-    def helper(self, n: int, row: int, pos: List[bool], pos2: List[int], ans: List[List[str]]):
-        if row == n:
-            self.construct(n, pos2, ans)
-            return
-        for i in range(n):
-            index = n + 2 * n - 1 + n - 1 + i - row
-            if pos[i] or pos[n + i + row] or pos[index]:
-                continue
-            pos[i] = True
-            pos[n + i + row] = True
-            pos[index] = True
-            pos2[row] = i
-            self.helper(n, row + 1, pos, pos2, ans)
-            pos[i] = False
-            pos[n + i + row] = False
-            pos[index] = False
-
-    def construct(self, n: int, pos: list[int], ans: list[list[str]]):
-        sol = []
-        for r in range(n):
-            queenRow = ['.'] * n
-            queenRow[pos[r]] = 'Q'
-            sol.append(''.join(queenRow))
-        ans.append(sol)
-```
\ No newline at end of file
+    def solveNQueens(self, n):
+        def is_safe(row, col):
+            # Check for queens in the same column
+            for i in range(row):
+                if board[i][col] == 'Q':
+                    return False
+            
+            # Check for queens in the upper-left diagonal
+            for i, j in zip(range(row-1, -1, -1), range(col-1, -1, -1)):
+                if board[i][j] == 'Q':
+                    return False
+            
+            # Check for queens in the upper-right diagonal
+            for i, j in zip(range(row-1, -1, -1), range(col+1, n)):
+                if board[i][j] == 'Q':
+                    return False
+            
+            return True
+        
+        def backtrack(row):
+            if row == n:
+                solutions.append([''.join(row) for row in board])
+                return
+            
+            for col in range(n):
+                if is_safe(row, col):
+                    board[row][col] = 'Q'
+                    backtrack(row + 1)
+                    board[row][col] = '.'
+        
+        board = [ ['.' for _ in range(n)] for _ in range(n)]
+        solutions = []
+        backtrack(0)
+        return solutions
+
+# Example Usage:
+solution = Solution()
+print(solution.solveNQueens(4))  # Output: [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
+print(solution.solveNQueens(1))  # Output: [["Q"]]
+```
+
+This code defines a `Solution` class with a `solveNQueens` method to find all distinct solutions to the N-Queens puzzle. The example usage demonstrates how to create an instance of the `Solution` class and call the `solveNQueens` method with different values of `n`.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0053_maximum_subarray/readme.md b/src/main/python/g0001_0100/s0053_maximum_subarray/readme.md
index 9d74127..8a0b7a9 100644
--- a/src/main/python/g0001_0100/s0053_maximum_subarray/readme.md
+++ b/src/main/python/g0001_0100/s0053_maximum_subarray/readme.md
@@ -36,19 +36,47 @@ A **subarray** is a **contiguous** part of an array.
 
 **Follow up:** If you have figured out the `O(n)` solution, try coding another solution using the **divide and conquer** approach, which is more subtle.
 
-## Solution
+To solve the Maximum Subarray problem, we can use the Kadane's algorithm, which efficiently finds the maximum subarray sum in linear time. Here are the steps to solve the task:
+
+1. **Initialize Variables:** 
+   - Initialize two variables `max_sum` and `current_sum` to keep track of the maximum sum found so far and the sum of the current subarray, respectively.
+   - Set `max_sum` and `current_sum` to the value of the first element in the array `nums`.
+
+2. **Iterate Through the Array:**
+   - Start iterating through the array `nums` from the second element (index 1).
+   - For each element `num` in `nums`, do the following:
+     - Update `current_sum` to be the maximum of either `num` or `current_sum + num`. This step ensures that we consider either starting a new subarray or extending the current subarray.
+     - Update `max_sum` to be the maximum of either `max_sum` or `current_sum`. This step ensures that we keep track of the maximum subarray sum found so far.
+
+3. **Return the Result:**
+   - After iterating through the entire array, `max_sum` will contain the maximum subarray sum.
+   - Return `max_sum` as the result.
+
+### Python Implementation:
 
 ```python
 class Solution:
     def maxSubArray(self, nums: List[int]) -> int:
-        maxi = float('-inf')
-        sum_val = 0
-        for num in nums:
-            # calculating sub-array sum
-            sum_val += num
-            maxi = max(sum_val, maxi)
-            if sum_val < 0:
-                # there is no point to carry a -ve subarray sum. hence setting to 0
-                sum_val = 0
-        return maxi
-```
\ No newline at end of file
+        # Initialize variables
+        max_sum = current_sum = nums[0]
+
+        # Iterate through the array
+        for num in nums[1:]:
+            current_sum = max(num, current_sum + num)
+            max_sum = max(max_sum, current_sum)
+
+        return max_sum
+
+# Example Usage:
+solution = Solution()
+nums1 = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
+print(solution.maxSubArray(nums1))  # Output: 6
+
+nums2 = [1]
+print(solution.maxSubArray(nums2))  # Output: 1
+
+nums3 = [5, 4, -1, 7, 8]
+print(solution.maxSubArray(nums3))  # Output: 23
+```
+
+This algorithm has a time complexity of O(n), where n is the length of the input array `nums`. Therefore, it efficiently finds the maximum subarray sum.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0055_jump_game/readme.md b/src/main/python/g0001_0100/s0055_jump_game/readme.md
index e27ee01..327969d 100644
--- a/src/main/python/g0001_0100/s0055_jump_game/readme.md
+++ b/src/main/python/g0001_0100/s0055_jump_game/readme.md
@@ -30,14 +30,46 @@ Return `true` _if you can reach the last index, or_ `false` _otherwise_.
 *   <code>1 <= nums.length <= 10<sup>4</sup></code>
 *   <code>0 <= nums[i] <= 10<sup>5</sup></code>
 
-## Solution
+To solve the "Jump Game" problem, you can follow these steps:
+
+1. **Initialize Variables:** Start by initializing a variable `max_reach` to store the maximum reachable index. Initially, set `max_reach` to `0`, as you are at the first index.
+   
+2. **Iterate through the Array:** Traverse through the array `nums` starting from index `0` to `n-1`, where `n` is the length of the array.
+
+3. **Update Maximum Reach:** At each index `i`, update `max_reach` to be the maximum of `max_reach` and `i + nums[i]`. This indicates the farthest index you can reach from the current position `i`.
+
+4. **Check for End Reachability:** While traversing the array, if at any point `max_reach` becomes greater than or equal to the last index (i.e., `n - 1`), return `True`, indicating that you can reach the end of the array.
+
+5. **Handle Zero Reach:** If the current index `i` is greater than `max_reach`, it means you cannot progress further, and thus, return `False`.
+
+6. **Return Result:** After iterating through the entire array, if you haven't reached the end of the array, return `False`, as you cannot reach the last index.
+
+Here's a Python function implementing the above steps:
 
 ```python
+from typing import List
+
 class Solution:
     def canJump(self, nums: List[int]) -> bool:
-        goal = len(nums) - 1
-        for i in range(len(nums) - 1, -1, -1):
-            if i + nums[i] >= goal:
-                goal = i
-        return True if goal == 0 else False
-```
\ No newline at end of file
+        max_reach = 0
+        n = len(nums)
+        
+        for i in range(n):
+            if i > max_reach:
+                return False
+            max_reach = max(max_reach, i + nums[i])
+            if max_reach >= n - 1:
+                return True
+        
+        return False
+
+# Example usage:
+nums1 = [2, 3, 1, 1, 4]
+nums2 = [3, 2, 1, 0, 4]
+
+sol = Solution()
+print(sol.canJump(nums1))  # Output: True
+print(sol.canJump(nums2))  # Output: False
+```
+
+You can then test this function with different input arrays to verify its correctness.
\ No newline at end of file
diff --git a/src/main/python/g0001_0100/s0056_merge_intervals/readme.md b/src/main/python/g0001_0100/s0056_merge_intervals/readme.md
index c04d613..c90738f 100644
--- a/src/main/python/g0001_0100/s0056_merge_intervals/readme.md
+++ b/src/main/python/g0001_0100/s0056_merge_intervals/readme.md
@@ -29,6 +29,43 @@ Given an array of `intervals` where <code>intervals[i] = [start<sub>i</sub>, end
 *   `intervals[i].length == 2`
 *   <code>0 <= start<sub>i</sub> <= end<sub>i</sub> <= 10<sup>4</sup></code>
 
+Here are the steps to solve the task using the `Solution` class:
+
+1. Define the `Solution` class with a method named `merge` that takes in a list of intervals.
+2. Inside the `merge` method, sort the intervals based on their start times.
+3. Initialize an empty list called `merged_intervals` to store the merged intervals.
+4. Iterate through the sorted intervals.
+5. For each interval, if the `merged_intervals` list is empty or if the current interval's start time is greater than the end time of the last interval in the `merged_intervals` list, append the current interval to `merged_intervals`.
+6. Otherwise, merge the current interval with the last interval in the `merged_intervals` list by updating the end time of the last interval if the current interval's end time is greater.
+7. After iterating through all intervals, return the `merged_intervals` list.
+
+Here's the implementation:
+
+```python
+from typing import List
+
+class Solution:
+    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
+        intervals.sort(key=lambda x: x[0])
+        merged_intervals = []
+        
+        for interval in intervals:
+            if not merged_intervals or interval[0] > merged_intervals[-1][1]:
+                merged_intervals.append(interval)
+            else:
+                merged_intervals[-1][1] = max(merged_intervals[-1][1], interval[1])
+        
+        return merged_intervals
+
+# Example usage:
+intervals1 = \[\[1, 3], [2, 6], [8, 10], [15, 18]]
+intervals2 = \[\[1, 4], [4, 5]]
+
+sol = Solution()
+print(sol.merge(intervals1))  # Output: [[1, 6], [8, 10], [15, 18]]
+print(sol.merge(intervals2))  # Output: [[1, 5]]
+```
+
 ## Solution
 
 ```python
diff --git a/src/main/python/g0101_0200/s0101_symmetric_tree/readme.md b/src/main/python/g0101_0200/s0101_symmetric_tree/readme.md
index 18150d4..5f82fb6 100644
--- a/src/main/python/g0101_0200/s0101_symmetric_tree/readme.md
+++ b/src/main/python/g0101_0200/s0101_symmetric_tree/readme.md
@@ -30,7 +30,17 @@ Given the `root` of a binary tree, _check whether it is a mirror of itself_ (i.e
 
 **Follow up:** Could you solve it both recursively and iteratively?
 
-## Solution
+To solve the "Symmetric Tree" problem in Python with the Solution class, follow these steps:
+
+1. Define a method `isSymmetric` in the `Solution` class that takes the root of a binary tree as input and returns true if the tree is symmetric, and false otherwise.
+2. Implement a recursive approach to check if the given binary tree is symmetric:
+   - Define a helper method `isMirror` that takes two tree nodes as input parameters.
+   - In the `isMirror` method, recursively compare the left and right subtrees of the given nodes.
+   - At each step, check if the values of the corresponding nodes are equal and if the left subtree of one node is a mirror image of the right subtree of the other node.
+   - If both conditions are satisfied for all corresponding nodes, return true; otherwise, return false.
+3. Call the `isMirror` method with the root's left and right children to check if the entire tree is symmetric.
+
+Here's the implementation of the `isSymmetric` method in Python:
 
 ```python
 # Definition for a binary tree node.
@@ -40,7 +50,7 @@ Given the `root` of a binary tree, _check whether it is a mirror of itself_ (i.e
 #         self.left = left
 #         self.right = right
 class Solution:
-    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
+    def isSymmetric(self, root: TreeNode) -> bool:
         if root is None:
             return True
         return self.helper(root.left, root.right)
@@ -51,4 +61,6 @@ class Solution:
         if leftNode.val != rightNode.val:
             return False
         return self.helper(leftNode.left, rightNode.right) and self.helper(leftNode.right, rightNode.left)
-```
\ No newline at end of file
+```
+
+This implementation recursively checks whether the given binary tree is symmetric around its center in O(n) time complexity, where n is the number of nodes in the tree.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0102_binary_tree_level_order_traversal/readme.md b/src/main/python/g0101_0200/s0102_binary_tree_level_order_traversal/readme.md
index a63dfcd..3556fb5 100644
--- a/src/main/python/g0101_0200/s0102_binary_tree_level_order_traversal/readme.md
+++ b/src/main/python/g0101_0200/s0102_binary_tree_level_order_traversal/readme.md
@@ -32,7 +32,25 @@ Given the `root` of a binary tree, return _the level order traversal of its node
 *   The number of nodes in the tree is in the range `[0, 2000]`.
 *   `-1000 <= Node.val <= 1000`
 
-## Solution
+To solve the "Binary Tree Level Order Traversal" problem in Python with a `Solution` class, we'll perform a breadth-first search (BFS) traversal of the binary tree. Below are the steps:
+
+1. **Create a `Solution` class**: Define a class named `Solution` to encapsulate our solution methods.
+
+2. **Create a `levelOrder` method**: This method takes the root node of the binary tree as input and returns the level order traversal of its nodes' values.
+
+3. **Initialize a queue**: Create a queue to store the nodes during BFS traversal.
+
+4. **Check for null root**: Check if the root is null. If it is, return an empty list.
+
+5. **Perform BFS traversal**: Enqueue the root node into the queue. While the queue is not empty:
+   - Dequeue the front node from the queue.
+   - Add the value of the dequeued node to the current level list.
+   - Enqueue the left and right children of the dequeued node if they exist.
+   - Move to the next level when all nodes in the current level are processed.
+
+6. **Return the result**: After the BFS traversal is complete, return the list containing the level order traversal of the binary tree.
+
+Here's the Python implementation:
 
 ```python
 # Definition for a binary tree node.
@@ -41,11 +59,10 @@ Given the `root` of a binary tree, return _the level order traversal of its node
 #         self.val = val
 #         self.left = left
 #         self.right = right
-
 from collections import deque
 
 class Solution:
-    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
+    def levelOrder(self, root: TreeNode) -> List[List[int]]:
         result = []
         if not root:
             return result
@@ -70,4 +87,6 @@ class Solution:
                     queue.append(None)
         
         return result
-```
\ No newline at end of file
+```
+
+This implementation follows the steps outlined above and efficiently computes the level order traversal of the binary tree in Python using BFS.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0104_maximum_depth_of_binary_tree/readme.md b/src/main/python/g0101_0200/s0104_maximum_depth_of_binary_tree/readme.md
index 403abea..c8dd192 100644
--- a/src/main/python/g0101_0200/s0104_maximum_depth_of_binary_tree/readme.md
+++ b/src/main/python/g0101_0200/s0104_maximum_depth_of_binary_tree/readme.md
@@ -40,7 +40,19 @@ A binary tree's **maximum depth** is the number of nodes along the longest path
 *   The number of nodes in the tree is in the range <code>[0, 10<sup>4</sup>]</code>.
 *   `-100 <= Node.val <= 100`
 
-## Solution
+To solve the "Maximum Depth of Binary Tree" problem in Python with a `Solution` class, we'll perform a depth-first search (DFS) traversal of the binary tree. Below are the steps:
+
+1. **Create a `Solution` class**: Define a class named `Solution` to encapsulate our solution methods.
+
+2. **Create a `maxDepth` method**: This method takes the root node of the binary tree as input and returns its maximum depth.
+
+3. **Check for null root**: Check if the root is null. If it is, return 0 as the depth.
+
+4. **Perform DFS traversal**: Recursively compute the depth of the left and right subtrees. The maximum depth of the binary tree is the maximum depth of its left and right subtrees, plus 1 for the current node.
+
+5. **Return the result**: After the DFS traversal is complete, return the maximum depth of the binary tree.
+
+Here's the Python implementation:
 
 ```python
 # Definition for a binary tree node.
@@ -57,4 +69,6 @@ class Solution:
             self.maxDepth(root.left),
             self.maxDepth(root.right),
         )
-```
\ No newline at end of file
+```
+
+This implementation follows the steps outlined above and efficiently computes the maximum depth of the binary tree in Python using DFS traversal.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0105_construct_binary_tree_from_preorder_and_inorder_traversal/readme.md b/src/main/python/g0101_0200/s0105_construct_binary_tree_from_preorder_and_inorder_traversal/readme.md
index b27566a..0c1aa7d 100644
--- a/src/main/python/g0101_0200/s0105_construct_binary_tree_from_preorder_and_inorder_traversal/readme.md
+++ b/src/main/python/g0101_0200/s0105_construct_binary_tree_from_preorder_and_inorder_traversal/readme.md
@@ -31,7 +31,32 @@ Given two integer arrays `preorder` and `inorder` where `preorder` is the preord
 *   `preorder` is **guaranteed** to be the preorder traversal of the tree.
 *   `inorder` is **guaranteed** to be the inorder traversal of the tree.
 
-## Solution
+To solve the "Construct Binary Tree from Preorder and Inorder Traversal" problem in Python with a `Solution` class, we'll use a recursive approach. Below are the steps:
+
+1. **Create a `Solution` class**: Define a class named `Solution` to encapsulate our solution methods.
+
+2. **Create a `buildTree` method**: This method takes two integer arrays, `preorder` and `inorder`, as input and returns the constructed binary tree.
+
+3. **Check for empty arrays**: Check if either of the arrays `preorder` or `inorder` is empty. If so, return null, as there's no tree to construct.
+
+4. **Define a helper method**: Define a recursive helper method `build` to construct the binary tree.
+   - The method should take the indices representing the current subtree in both `preorder` and `inorder`.
+   - The start and end indices in `preorder` represent the current subtree's preorder traversal.
+   - The start and end indices in `inorder` represent the current subtree's inorder traversal.
+   
+5. **Base case**: If the start index of `preorder` is greater than the end index or if the start index of `inorder` is greater than the end index, return null.
+
+6. **Find the root node**: The root node is the first element in the `preorder` array.
+
+7. **Find the root's position in `inorder`**: Iterate through the `inorder` array to find the root's position.
+
+8. **Recursively build left and right subtrees**: 
+   - Recursively call the `build` method for the left subtree with updated indices.
+   - Recursively call the `build` method for the right subtree with updated indices.
+   
+9. **Return the root node**: After constructing the left and right subtrees, return the root node.
+
+Here's the Python implementation:
 
 ```python
 # Definition for a binary tree node.
@@ -64,4 +89,6 @@ class Solution:
         for i in range(len(preorder)):
             self.map[inorder[i]] = i
         return self.answer(preorder, inorder, 0, len(preorder) - 1)
-```
\ No newline at end of file
+```
+
+This implementation follows the steps outlined above and efficiently constructs the binary tree from preorder and inorder traversals in Python.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0114_flatten_binary_tree_to_linked_list/readme.md b/src/main/python/g0101_0200/s0114_flatten_binary_tree_to_linked_list/readme.md
index b712deb..e931388 100644
--- a/src/main/python/g0101_0200/s0114_flatten_binary_tree_to_linked_list/readme.md
+++ b/src/main/python/g0101_0200/s0114_flatten_binary_tree_to_linked_list/readme.md
@@ -37,7 +37,27 @@ Given the `root` of a binary tree, flatten the tree into a "linked list":
 
 **Follow up:** Can you flatten the tree in-place (with `O(1)` extra space)?
 
-## Solution
+To solve the "Flatten Binary Tree to Linked List" problem in Python with a `Solution` class, we'll use a recursive approach. Below are the steps:
+
+1. **Create a `Solution` class**: Define a class named `Solution` to encapsulate our solution methods.
+
+2. **Create a `flatten` method**: This method takes the root node of the binary tree as input and flattens the tree into a linked list using preorder traversal.
+
+3. **Check for null root**: Check if the root is null. If so, there's no tree to flatten, so return.
+
+4. **Recursively flatten the tree**: Define a recursive helper method `flattenTree` to perform the flattening.
+   - The method should take the current node as input.
+   - Perform a preorder traversal of the tree.
+   - For each node, if it has a left child:
+     - Find the rightmost node in the left subtree.
+     - Attach the right subtree of the current node to the right of the rightmost node.
+     - Move the left subtree to the right subtree position.
+     - Set the left child of the current node to null.
+   - Recursively call the method for the right child.
+
+5. **Call the helper method**: Call the `flattenTree` method with the root node.
+
+Here's the Python implementation:
 
 ```python
 # Definition for a binary tree node.
@@ -70,5 +90,7 @@ class Solution:
         if tail.right is None:
             return tail
         else:
-            return self.find_tail(tail.right)
-```
\ No newline at end of file
+            return self.find_tail(tail.right)   
+```
+
+This implementation follows the steps outlined above and efficiently flattens the binary tree into a linked list using preorder traversal in Python.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0121_best_time_to_buy_and_sell_stock/readme.md b/src/main/python/g0101_0200/s0121_best_time_to_buy_and_sell_stock/readme.md
index e473383..55d37f8 100644
--- a/src/main/python/g0101_0200/s0121_best_time_to_buy_and_sell_stock/readme.md
+++ b/src/main/python/g0101_0200/s0121_best_time_to_buy_and_sell_stock/readme.md
@@ -32,7 +32,22 @@ Return _the maximum profit you can achieve from this transaction_. If you cannot
 *   <code>1 <= prices.length <= 10<sup>5</sup></code>
 *   <code>0 <= prices[i] <= 10<sup>4</sup></code>
 
-## Solution
+To solve the "Best Time to Buy and Sell Stock" problem in Python with a `Solution` class, we'll use a greedy algorithm. Below are the steps:
+
+1. **Create a `Solution` class**: Define a class named `Solution` to encapsulate our solution methods.
+
+2. **Create a `maxProfit` method**: This method takes an array `prices` as input and returns the maximum profit that can be achieved by buying and selling the stock.
+
+3. **Initialize variables**: Initialize two variables, `minPrice` to store the minimum price seen so far and `maxProfit` to store the maximum profit seen so far. Initialize `maxProfit` to 0.
+
+4. **Iterate through the prices array**:
+   - For each price in the array:
+     - Update `minPrice` to the minimum of the current price and `minPrice`.
+     - Update `maxProfit` to the maximum of the current profit (price - `minPrice`) and `maxProfit`.
+
+5. **Return the maximum profit**: After iterating through the entire array, return `maxProfit`.
+
+Here's the Python implementation:
 
 ```python
 class Solution:
@@ -47,4 +62,6 @@ class Solution:
                 max_profit = price - min_price
 
         return max_profit
-```
\ No newline at end of file
+```
+
+This implementation follows the steps outlined above and efficiently calculates the maximum profit that can be achieved by buying and selling the stock in Python.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0124_binary_tree_maximum_path_sum/readme.md b/src/main/python/g0101_0200/s0124_binary_tree_maximum_path_sum/readme.md
index c0a698b..229473c 100644
--- a/src/main/python/g0101_0200/s0124_binary_tree_maximum_path_sum/readme.md
+++ b/src/main/python/g0101_0200/s0124_binary_tree_maximum_path_sum/readme.md
@@ -36,20 +36,37 @@ Given the `root` of a binary tree, return _the maximum **path sum** of any **non
 *   The number of nodes in the tree is in the range <code>[1, 3 * 10<sup>4</sup>]</code>.
 *   `-1000 <= Node.val <= 1000`
 
-## Solution
+To solve the "Binary Tree Maximum Path Sum" problem in Python with a `Solution` class, we'll use a recursive approach. Below are the steps:
+
+1. **Create a `Solution` class**: Define a class named `Solution` to encapsulate our solution methods.
+
+2. **Create a `maxPathSum` method**: This method takes the root node of the binary tree as input and returns the maximum path sum.
+
+3. **Define a recursive helper method**: Define a recursive helper method `maxSumPath` to compute the maximum path sum rooted at the current node.
+   - The method should return the maximum path sum that can be obtained from the current node to any of its descendants.
+   - We'll use a post-order traversal to traverse the tree.
+   - For each node:
+     - Compute the maximum path sum for the left and right subtrees recursively.
+     - Update the maximum path sum by considering three cases:
+       1. The current node itself.
+       2. The current node plus the maximum path sum of the left subtree.
+       3. The current node plus the maximum path sum of the right subtree.
+     - Update the global maximum path sum if necessary by considering the sum of the current node, left subtree, and right subtree.
+
+4. **Initialize a variable to store the maximum path sum**: Initialize a global variable `maxSum` to store the maximum path sum.
+
+5. **Call the helper method**: Call the `maxSumPath` method with the root node.
+
+6. **Return the maximum path sum**: After traversing the entire tree, return the `maxSum`.
+
+Here's the Python implementation:
 
 ```python
-# 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 __init__(self):
         self.max_sum = float('-inf')
 
-    def maxPathSum(self, root: Optional[TreeNode]) -> int:
+    def maxPathSum(self, root: TreeNode) -> int:
         self.helper(root)
         return self.max_sum
 
@@ -64,4 +81,6 @@ class Solution:
         self.max_sum = max(self.max_sum, current)
         
         return root.val + max(left, right)
-```
\ No newline at end of file
+```
+
+This implementation follows the steps outlined above and efficiently computes the maximum path sum in a binary tree in Python.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0128_longest_consecutive_sequence/readme.md b/src/main/python/g0101_0200/s0128_longest_consecutive_sequence/readme.md
index 451c9d3..351a736 100644
--- a/src/main/python/g0101_0200/s0128_longest_consecutive_sequence/readme.md
+++ b/src/main/python/g0101_0200/s0128_longest_consecutive_sequence/readme.md
@@ -28,7 +28,23 @@ You must write an algorithm that runs in `O(n)` time.
 *   <code>0 <= nums.length <= 10<sup>5</sup></code>
 *   <code>-10<sup>9</sup> <= nums[i] <= 10<sup>9</sup></code>
 
-## Solution
+To solve the "Longest Consecutive Sequence" problem in Python with a `Solution` class, we'll use a HashSet and a greedy approach. Below are the steps:
+
+1. **Create a `Solution` class**: Define a class named `Solution` to encapsulate our solution methods.
+
+2. **Create a `longestConsecutive` method**: This method takes an array `nums` as input and returns the length of the longest consecutive elements sequence.
+
+3. **Initialize a HashSet**: Create a HashSet named `numSet` to store all the numbers in the array `nums`.
+
+4. **Iterate through the array**: Add all the numbers from the array `nums` to the `numSet`.
+
+5. **Find the longest sequence**: Iterate through the array `nums` again. For each number `num` in the array:
+   - Check if `num - 1` exists in the `numSet`. If it does not, `num` could be the start of a new sequence.
+   - If `num - 1` does not exist, start a new sequence from `num`. Increment `currentNum` by 1 and check if `currentNum` exists in the `numSet`. Keep incrementing `currentNum` until it does not exist in the `numSet`. Update the maximum length of the sequence accordingly.
+
+6. **Return the maximum length**: After iterating through the entire array, return the maximum length of the consecutive sequence.
+
+Here's the Python implementation:
 
 ```python
 class Solution:
@@ -48,4 +64,6 @@ class Solution:
                 max_length = max(max_length, cur_length)
         
         return max_length
-```
\ No newline at end of file
+```
+
+This implementation follows the steps outlined above and efficiently calculates the length of the longest consecutive elements sequence in Python.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0142_linked_list_cycle_ii/readme.md b/src/main/python/g0101_0200/s0142_linked_list_cycle_ii/readme.md
index 05edcbb..32030fb 100644
--- a/src/main/python/g0101_0200/s0142_linked_list_cycle_ii/readme.md
+++ b/src/main/python/g0101_0200/s0142_linked_list_cycle_ii/readme.md
@@ -49,35 +49,66 @@ There is a cycle in a linked list if there is some node in the list that can be
 
 **Follow up:** Can you solve it using `O(1)` (i.e. constant) memory?
 
-## Solution
+To solve the problem, we can use Floyd's Tortoise and Hare algorithm, also known as the Floyd's Cycle Detection algorithm. This algorithm involves two pointers, one moving at twice the speed of the other. If there's a cycle in the linked list, these two pointers will eventually meet. Once they meet, we reset one pointer to the head of the list and move both pointers at the same speed. The point where they meet again will be the start of the cycle.
+
+Here's how we can implement this algorithm in Python using a `Solution` class:
 
 ```python
-# Definition for singly-linked list.
-# class ListNode:
-#     def __init__(self, x):
-#         self.val = x
-#         self.next = None
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
 class Solution:
-    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:        
-        if not head or not head.next:
-            return None
+    def detectCycle(self, head: ListNode) -> ListNode:
+        # Function to detect cycle and return the node where cycle starts
         
-        slow = head
-        fast = head
+        # Step 1: Initialize slow and fast pointers
+        slow = fast = head
         
+        # Step 2: Find the meeting point of the two pointers
         while fast and fast.next:
-            fast = fast.next.next
             slow = slow.next
+            fast = fast.next.next
             if slow == fast:
                 break
         
+        # If there's no cycle, return None
         if not fast or not fast.next:
             return None
         
+        # Step 3: Reset one pointer to the head and move both pointers at the same speed
         slow = head
         while slow != fast:
             slow = slow.next
             fast = fast.next
         
+        # Step 4: Return the node where the two pointers meet again (start of cycle)
         return slow
-```
\ No newline at end of file
+
+# Example usage:
+# Create linked list nodes
+node1 = ListNode(3)
+node2 = ListNode(2)
+node3 = ListNode(0)
+node4 = ListNode(-4)
+
+# Connect nodes to form a cycle
+node1.next = node2
+node2.next = node3
+node3.next = node4
+node4.next = node2  # This creates a cycle
+
+# Create an instance of Solution class
+solution = Solution()
+
+# Call detectCycle method to find the start of the cycle
+cycle_start = solution.detectCycle(node1)
+
+if cycle_start:
+    print("Tail connects to node index:", cycle_start.val)
+else:
+    print("No cycle")
+```
+
+This solution has a time complexity of O(n) and uses O(1) extra space.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0146_lru_cache/readme.md b/src/main/python/g0101_0200/s0146_lru_cache/readme.md
index 7082d53..140e745 100644
--- a/src/main/python/g0101_0200/s0146_lru_cache/readme.md
+++ b/src/main/python/g0101_0200/s0146_lru_cache/readme.md
@@ -41,74 +41,104 @@ The functions `get` and `put` must each run in `O(1)` average time complexity.
 *   <code>0 <= value <= 10<sup>5</sup></code>
 *   At most 2<code> * 10<sup>5</sup></code> calls will be made to `get` and `put`.
 
-## Solution
+To solve the problem and implement the LRU Cache, we can use a combination of a dictionary (hash map) and a doubly linked list. This approach allows us to achieve O(1) time complexity for both the `get` and `put` operations.
 
-```python
-class LRUCacheNode:
-    def __init__(self, key, value):
-        self.key = key
-        self.value = value
-        self.prev = None
-        self.next = None
+### Steps:
+
+1. **Define a Doubly Linked List Node**:
+   - Define a class for the doubly linked list node with attributes `key`, `value`, `prev`, and `next`.
+
+2. **Initialize the LRU Cache**:
+   - Initialize the LRU cache with a dictionary to store key-value pairs and two dummy nodes for the head and tail of the doubly linked list.
+   - Set `capacity` to the provided capacity.
+   - Initialize a `size` variable to keep track of the number of elements in the cache.
+
+3. **Implement `get` Operation**:
+   - If the key exists in the cache, move the corresponding node to the front of the doubly linked list (indicating it was recently used) and return its value.
+   - If the key does not exist, return -1.
+
+4. **Implement `put` Operation**:
+   - If the key exists in the cache, update its value and move the corresponding node to the front of the doubly linked list.
+   - If the key does not exist:
+     - If the cache is full (`size` equals `capacity`), remove the least recently used node (tail node) from the doubly linked list and the dictionary.
+     - Create a new node with the provided key and value, add it to the front of the doubly linked list, and insert the key-value pair into the dictionary.
+   - Update the `size` accordingly.
 
+### Implementation:
+
+```python
 class LRUCache:
+    class ListNode:
+        def __init__(self, key=0, value=0):
+            self.key = key
+            self.value = value
+            self.prev = None
+            self.next = None
+
     def __init__(self, capacity: int):
         self.capacity = capacity
-        self.cache_map = {}
-        self.head = None
-        self.tail = None
+        self.cache = {}
+        self.head = self.ListNode()
+        self.tail = self.ListNode()
+        self.head.next = self.tail
+        self.tail.prev = self.head
+        self.size = 0
+
+    def _add_node(self, node):
+        node.prev = self.head
+        node.next = self.head.next
+        self.head.next.prev = node
+        self.head.next = node
+
+    def _remove_node(self, node):
+        prev_node = node.prev
+        next_node = node.next
+        prev_node.next = next_node
+        next_node.prev = prev_node
+
+    def _move_to_front(self, node):
+        self._remove_node(node)
+        self._add_node(node)
 
     def get(self, key: int) -> int:
-        if key in self.cache_map:
-            node = self.cache_map[key]
-            self.move_to_head(node)
+        if key in self.cache:
+            node = self.cache[key]
+            self._move_to_front(node)
             return node.value
-        return -1
+        else:
+            return -1
 
     def put(self, key: int, value: int) -> None:
-        if key in self.cache_map:
-            node = self.cache_map[key]
+        if key in self.cache:
+            node = self.cache[key]
             node.value = value
-            self.move_to_head(node)
+            self._move_to_front(node)
         else:
-            if len(self.cache_map) < self.capacity:
-                node = LRUCacheNode(key, value)
-                self.cache_map[key] = node
-                if not self.head:
-                    self.head = node
-                    self.tail = node
-                else:
-                    node.next = self.head
-                    self.head.prev = node
-                    self.head = node
-            else:
-                last = self.tail
-                if last:
-                    self.tail = last.prev
-                    if self.tail:
-                        self.tail.next = None
-                    self.cache_map.pop(last.key)
-                    if not self.cache_map:
-                        self.head = None
-                self.put(key, value)
-
-    def move_to_head(self, node: LRUCacheNode) -> None:
-        if node == self.head:
-            return
-        if node == self.tail:
-            self.tail = node.prev
-        if node.prev:
-            node.prev.next = node.next
-        if node.next:
-            node.next.prev = node.prev
-        node.prev = None
-        node.next = self.head
-        if self.head:
-            self.head.prev = node
-        self.head = node
-
-# Your LRUCache object will be instantiated and called as such:
-# obj = LRUCache(capacity)
-# param_1 = obj.get(key)
-# obj.put(key,value)
-```
\ No newline at end of file
+            if self.size == self.capacity:
+                del self.cache[self.tail.prev.key]
+                self._remove_node(self.tail.prev)
+                self.size -= 1
+            new_node = self.ListNode(key, value)
+            self._add_node(new_node)
+            self.cache[key] = new_node
+            self.size += 1
+```
+
+### Explanation:
+
+1. **Define a Doubly Linked List Node**:
+   - We define a nested class `ListNode` to represent nodes in the doubly linked list. Each node contains `key`, `value`, `prev`, and `next` attributes.
+
+2. **Initialize the LRU Cache**:
+   - In the `__init__` method, we initialize the LRU cache with the provided `capacity`, an empty dictionary `cache` to store key-value pairs, and two dummy nodes `head` and `tail` for the head and tail of the doubly linked list. We set `head.next` to `tail` and `tail.prev` to `head` to link them together. We also initialize `size` to 0.
+
+3. **Implement `get` Operation**:
+   - In the `get` method, if the key exists in the cache, we move the corresponding node to the front of the doubly linked list using the `_move_to_front` method and return its value. If the key does not exist, we return -1.
+
+4. **Implement `put` Operation**:
+   - In the `put` method, if the key exists in the cache, we update its value and move the corresponding node to the front of the doubly linked list. If the key does not exist:
+     - If the cache is full, we remove the least recently used node (tail node) from the doubly linked list and the dictionary.
+     - We create a new node with the provided key and value, add it to the front of the doubly linked list, and insert the key-value pair into the dictionary.
+   - We update the `size` accordingly.
+
+This implementation ensures that both `get` and `put` operations run in O(1) average time complexity.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0148_sort_list/readme.md b/src/main/python/g0101_0200/s0148_sort_list/readme.md
index 8b4eb0f..14d4822 100644
--- a/src/main/python/g0101_0200/s0148_sort_list/readme.md
+++ b/src/main/python/g0101_0200/s0148_sort_list/readme.md
@@ -36,50 +36,95 @@ Given the `head` of a linked list, return _the list after sorting it in **ascend
 
 **Follow up:** Can you sort the linked list in `O(n logn)` time and `O(1)` memory (i.e. constant space)?
 
-## Solution
+To solve the problem of sorting a linked list, you can use the merge sort algorithm, which is suitable for linked lists because it provides an O(n log n) time complexity. This approach can be implemented recursively and achieves the required efficiency.
+
+Here are the detailed steps and the corresponding implementation using the `Solution` class:
+
+### Steps:
+
+1. **Base Case**:
+   - If the linked list is empty or has only one node, it is already sorted. Return the head.
+
+2. **Split the List**:
+   - Use the fast and slow pointer technique to find the middle of the linked list. This will help to split the linked list into two halves.
+   - `slow` moves one step at a time, while `fast` moves two steps at a time.
+   - When `fast` reaches the end, `slow` will be at the middle point of the list.
+
+3. **Sort Each Half**:
+   - Recursively sort the left half and the right half of the list.
+
+4. **Merge the Sorted Halves**:
+   - Merge the two sorted halves into a single sorted list.
+
+### Implementation:
 
 ```python
-# Definition for singly-linked list.
-# class ListNode:
-#     def __init__(self, val=0, next=None):
-#         self.val = val
-#         self.next = next
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
 class Solution:
-    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
+    def sortList(self, head: ListNode) -> ListNode:
         if not head or not head.next:
             return head
-
-        # Find the middle of the list
-        slow, fast = head, head
-        pre = slow
-        while fast and fast.next:
-            pre = slow
+        
+        # Step 2: Split the list into two halves
+        mid = self.getMid(head)
+        left = head
+        right = mid.next
+        mid.next = None
+        
+        # Step 3: Sort each half
+        left = self.sortList(left)
+        right = self.sortList(right)
+        
+        # Step 4: Merge the sorted halves
+        return self.merge(left, right)
+    
+    def getMid(self, head: ListNode) -> ListNode:
+        slow = head
+        fast = head
+        while fast.next and fast.next.next:
             slow = slow.next
             fast = fast.next.next
-        pre.next = None
-
-        # Sort the two halves
-        first = self.sortList(head)
-        second = self.sortList(slow)
-
-        # Merge the sorted halves
-        res = ListNode(0)
-        cur = res
-        while first or second:
-            if not first:
-                cur.next = second
-                break
-            elif not second:
-                cur.next = first
-                break
-            elif first.val <= second.val:
-                cur.next = first
-                first = first.next
-                cur = cur.next
+        return slow
+    
+    def merge(self, list1: ListNode, list2: ListNode) -> ListNode:
+        dummy = ListNode()
+        tail = dummy
+        
+        while list1 and list2:
+            if list1.val < list2.val:
+                tail.next = list1
+                list1 = list1.next
             else:
-                cur.next = second
-                second = second.next
-                cur = cur.next
-
-        return res.next
-```
\ No newline at end of file
+                tail.next = list2
+                list2 = list2.next
+            tail = tail.next
+        
+        if list1:
+            tail.next = list1
+        if list2:
+            tail.next = list2
+        
+        return dummy.next
+```
+
+### Explanation:
+
+1. **Base Case**:
+   - The function `sortList` checks if the list is empty or has a single node, in which case it returns the head as it is already sorted.
+
+2. **Split the List**:
+   - The `getMid` function finds the middle of the list using the fast and slow pointer technique.
+   - The list is then split into two halves: `left` starting from the head to the middle, and `right` starting from the node after the middle.
+
+3. **Sort Each Half**:
+   - The `sortList` function is called recursively on both halves to sort them.
+
+4. **Merge the Sorted Halves**:
+   - The `merge` function merges the two sorted halves into a single sorted linked list.
+   - A dummy node is used to simplify the merging process, and a `tail` pointer is used to build the new sorted list.
+
+This approach ensures that the linked list is sorted in O(n log n) time complexity, which is optimal for this problem. The space complexity is O(log n) due to the recursion stack.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0152_maximum_product_subarray/readme.md b/src/main/python/g0101_0200/s0152_maximum_product_subarray/readme.md
index 2eb0d96..12a72a3 100644
--- a/src/main/python/g0101_0200/s0152_maximum_product_subarray/readme.md
+++ b/src/main/python/g0101_0200/s0152_maximum_product_subarray/readme.md
@@ -33,28 +33,67 @@ A **subarray** is a contiguous subsequence of the array.
 *   `-10 <= nums[i] <= 10`
 *   The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.
 
-## Solution
+To solve the problem of finding the maximum product subarray, you can use a dynamic programming approach to keep track of the maximum and minimum products at each position in the array. This approach works because the product of two negative numbers can be positive, and thus the minimum product can become the maximum if a negative number is encountered.
+
+Here are the detailed steps and the corresponding implementation in the `Solution` class:
+
+### Steps:
+
+1. **Initialization**:
+   - Check if the input array `nums` is empty. If it is, return 0.
+   - Initialize three variables:
+     - `max_product` to keep track of the maximum product found so far.
+     - `current_max` to keep track of the maximum product ending at the current position.
+     - `current_min` to keep track of the minimum product ending at the current position.
+
+2. **Iterate through the Array**:
+   - Loop through each element in the array starting from the first element.
+   - For each element, calculate the potential new values for `current_max` and `current_min` considering the current element itself, the product of `current_max` with the current element, and the product of `current_min` with the current element.
+   - Update `current_max` to be the maximum of these values.
+   - Update `current_min` to be the minimum of these values.
+   - Update `max_product` to be the maximum of `max_product` and `current_max`.
+
+3. **Return Result**:
+   - After the loop, `max_product` will hold the maximum product of any subarray within `nums`.
+
+### Implementation:
 
 ```python
 class Solution:
     def maxProduct(self, nums: List[int]) -> int:
-        ans = float('-inf')
-        cprod = 1
-
-        # Forward pass
-        for num in nums:
-            cprod *= num
-            ans = max(ans, cprod)
-            if cprod == 0:
-                cprod = 1
-
-        # Backward pass
-        cprod = 1
-        for num in reversed(nums):
-            cprod *= num
-            ans = max(ans, cprod)
-            if cprod == 0:
-                cprod = 1
-
-        return ans
-```
\ No newline at end of file
+        if not nums:
+            return 0
+        
+        max_product = nums[0]
+        current_max = nums[0]
+        current_min = nums[0]
+        
+        for num in nums[1:]:
+            if num < 0:
+                current_max, current_min = current_min, current_max
+            
+            current_max = max(num, current_max * num)
+            current_min = min(num, current_min * num)
+            
+            max_product = max(max_product, current_max)
+        
+        return max_product
+```
+
+### Explanation:
+
+1. **Initialization**:
+   - `max_product` is initialized to the first element of the array because the maximum product subarray must include at least one element.
+   - `current_max` and `current_min` are also initialized to the first element.
+
+2. **Iterate through the Array**:
+   - For each element in `nums` (starting from the second element):
+     - If the current element is negative, swap `current_max` and `current_min` because multiplying by a negative number flips the maximum and minimum.
+     - Update `current_max` to be the maximum of the current element or the product of `current_max` with the current element.
+     - Update `current_min` to be the minimum of the current element or the product of `current_min` with the current element.
+     - Update `max_product` to be the maximum of `max_product` and `current_max`.
+
+3. **Return Result**:
+   - The `max_product` variable now contains the maximum product of any contiguous subarray.
+
+This solution efficiently finds the maximum product subarray in O(n) time complexity with O(1) additional space complexity.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0153_find_minimum_in_rotated_sorted_array/readme.md b/src/main/python/g0101_0200/s0153_find_minimum_in_rotated_sorted_array/readme.md
index 6d4df76..1d34908 100644
--- a/src/main/python/g0101_0200/s0153_find_minimum_in_rotated_sorted_array/readme.md
+++ b/src/main/python/g0101_0200/s0153_find_minimum_in_rotated_sorted_array/readme.md
@@ -48,31 +48,52 @@ You must write an algorithm that runs in `O(log n) time.`
 *   All the integers of `nums` are **unique**.
 *   `nums` is sorted and rotated between `1` and `n` times.
 
-## Solution
+To solve the problem, we can use a binary search approach. This method leverages the properties of the rotated array and achieves the required O(log n) time complexity.
+
+### Steps:
+
+1. **Initialization**:
+   - Define two pointers, `left` and `right`, initialized to the start and end of the array, respectively.
+
+2. **Binary Search**:
+   - While `left` is less than `right`, perform the following steps:
+     - Calculate the mid-point `mid` using integer division.
+     - Determine if the middle element is greater than the rightmost element:
+       - If `nums[mid]` is greater than `nums[right]`, it means the minimum element is in the right half of the array. Move the `left` pointer to `mid + 1`.
+       - Otherwise, the minimum element is in the left half or could be the `mid` itself. Move the `right` pointer to `mid`.
+
+3. **Return Result**:
+   - After the loop terminates, the `left` pointer will point to the minimum element in the array.
+
+### Implementation:
 
 ```python
 class Solution:
-    def findMinUtil(self, nums: List[int], l: int, r: int) -> int:
-        if l == r:
-            return nums[l]
-        
-        mid = (l + r) // 2
-        
-        if mid == l and nums[mid] < nums[r]:
-            return nums[l]
-        
-        if mid - 1 >= 0 and nums[mid - 1] > nums[mid]:
-            return nums[mid]
+    def findMin(self, nums: List[int]) -> int:
+        left, right = 0, len(nums) - 1
         
-        if nums[mid] < nums[l]:
-            return self.findMinUtil(nums, l, mid - 1)
-        elif nums[mid] > nums[r]:
-            return self.findMinUtil(nums, mid + 1, r)
+        while left < right:
+            mid = (left + right) // 2
+            if nums[mid] > nums[right]:
+                left = mid + 1
+            else:
+                right = mid
         
-        return self.findMinUtil(nums, l, mid - 1)
+        return nums[left]
+```
 
-    def findMin(self, nums: List[int]) -> int:
-        l = 0
-        r = nums.length - 1
-        return self.findMinUtil(nums, l, r)
-```
\ No newline at end of file
+### Explanation:
+
+1. **Initialization**:
+   - `left` starts at 0 and `right` starts at the last index of the array.
+
+2. **Binary Search**:
+   - The `while` loop runs as long as `left` is less than `right`.
+   - `mid` is calculated as the average of `left` and `right`.
+   - If the middle element `nums[mid]` is greater than `nums[right]`, it means the minimum value is in the right part of the array. We discard the left half by setting `left` to `mid + 1`.
+   - If `nums[mid]` is less than or equal to `nums[right]`, it means the minimum value is in the left part, including `mid`. We set `right` to `mid`.
+
+3. **Return Result**:
+   - When the loop terminates, `left` will be at the index of the minimum element, so we return `nums[left]`.
+
+This approach efficiently narrows down the search space by half in each iteration, ensuring a logarithmic time complexity.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0155_min_stack/readme.md b/src/main/python/g0101_0200/s0155_min_stack/readme.md
index 42ed91d..073b385 100644
--- a/src/main/python/g0101_0200/s0155_min_stack/readme.md
+++ b/src/main/python/g0101_0200/s0155_min_stack/readme.md
@@ -41,40 +41,79 @@ Implement the `MinStack` class:
 *   Methods `pop`, `top` and `getMin` operations will always be called on **non-empty** stacks.
 *   At most <code>3 * 10<sup>4</sup></code> calls will be made to `push`, `pop`, `top`, and `getMin`.
 
-## Solution
+To solve the problem and implement the `MinStack` class that supports `push`, `pop`, `top`, and `getMin` operations in constant time, we can use two stacks:
+
+1. **Main Stack**: This stack stores all the elements.
+2. **Min Stack**: This stack keeps track of the minimum elements. Whenever a new element is pushed onto the main stack, it is also pushed onto the min stack if it is less than or equal to the current minimum. When an element is popped from the main stack, it is also popped from the min stack if it is the current minimum.
+
+### Steps:
+
+1. **Initialization**:
+   - Create two stacks: `main_stack` and `min_stack`.
+
+2. **Push Operation**:
+   - Push the value onto `main_stack`.
+   - If `min_stack` is empty or the value is less than or equal to the top of `min_stack`, push the value onto `min_stack`.
+
+3. **Pop Operation**:
+   - Pop the value from `main_stack`.
+   - If the popped value is equal to the top of `min_stack`, pop it from `min_stack`.
+
+4. **Top Operation**:
+   - Return the top value of `main_stack`.
+
+5. **GetMin Operation**:
+   - Return the top value of `min_stack`.
+
+### Implementation:
 
 ```python
 class MinStack:
-    class Node:
-        def __init__(self, min_val, data, previous_node=None, next_node=None):
-            self.min = min_val
-            self.data = data
-            self.previous_node = previous_node
-            self.next_node = next_node
-
     def __init__(self):
-        self.current_node = None
-
-    def push(self, val):
-        if self.current_node is None:
-            self.current_node = self.Node(val, val)
-        else:
-            self.current_node.next_node = self.Node(min(self.current_node.min, val), val, self.current_node)
-            self.current_node = self.current_node.next_node
-
-    def pop(self):
-        self.current_node = self.current_node.previous_node
-
-    def top(self):
-        return self.current_node.data if self.current_node else None
-
-    def getMin(self):
-        return self.current_node.min if self.current_node else None
-
-# Your MinStack object will be instantiated and called as such:
-# obj = MinStack()
-# obj.push(val)
-# obj.pop()
-# param_3 = obj.top()
-# param_4 = obj.getMin()
-```
\ No newline at end of file
+        self.main_stack = []
+        self.min_stack = []
+
+    def push(self, val: int) -> None:
+        self.main_stack.append(val)
+        if not self.min_stack or val <= self.min_stack[-1]:
+            self.min_stack.append(val)
+
+    def pop(self) -> None:
+        if self.main_stack:
+            if self.main_stack[-1] == self.min_stack[-1]:
+                self.min_stack.pop()
+            self.main_stack.pop()
+
+    def top(self) -> int:
+        if self.main_stack:
+            return self.main_stack[-1]
+
+    def getMin(self) -> int:
+        if self.min_stack:
+            return self.min_stack[-1]
+```
+
+### Explanation:
+
+1. **Initialization**:
+   - The `__init__` method initializes `main_stack` and `min_stack` as empty lists.
+
+2. **Push Operation**:
+   - `push(val: int) -> None`: 
+     - Adds `val` to `main_stack`.
+     - If `min_stack` is empty or `val` is less than or equal to the current minimum (top of `min_stack`), it adds `val` to `min_stack`.
+
+3. **Pop Operation**:
+   - `pop() -> None`: 
+     - Removes the top element from `main_stack`.
+     - If this element is the same as the top element of `min_stack`, it removes the top element from `min_stack` as well.
+
+4. **Top Operation**:
+   - `top() -> int`: 
+     - Returns the top element of `main_stack`.
+
+5. **GetMin Operation**:
+   - `getMin() -> int`: 
+     - Returns the top element of `min_stack`, which is the current minimum in the stack.
+
+This implementation ensures that all operations (`push`, `pop`, `top`, and `getMin`) are performed in constant time O(1).
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0160_intersection_of_two_linked_lists/readme.md b/src/main/python/g0101_0200/s0160_intersection_of_two_linked_lists/readme.md
index 1df409d..0d7f5dd 100644
--- a/src/main/python/g0101_0200/s0160_intersection_of_two_linked_lists/readme.md
+++ b/src/main/python/g0101_0200/s0160_intersection_of_two_linked_lists/readme.md
@@ -70,19 +70,71 @@ The judge will then create the linked structure based on these inputs and pass t
 
 **Follow up:** Could you write a solution that runs in `O(n)` time and use only `O(1)` memory?
 
-## Solution
+To solve the problem of finding the intersection of two linked lists, we can use an efficient approach that leverages the properties of linked lists and ensures that the solution runs in O(n) time and uses O(1) extra space.
+
+### Steps:
+
+1. **Calculate the Lengths**:
+   - Traverse both linked lists to calculate their lengths.
+
+2. **Align the Starting Points**:
+   - If one list is longer than the other, advance the pointer of the longer list by the difference in lengths. This way, both pointers are equidistant from the intersection point (if it exists).
+
+3. **Find the Intersection**:
+   - Traverse both lists simultaneously, comparing nodes to see if they are the same. The first common node is the intersection point.
+
+### Implementation:
 
 ```python
-# Definition for singly-linked list.
-# class ListNode:
-#     def __init__(self, x):
-#         self.val = x
-#         self.next = None
+class ListNode:
+    def __init__(self, val=0, next=None):
+        self.val = val
+        self.next = next
+
 class Solution:
-    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
-        node1, node2 = headA, headB
-        while node1 != node2:
-            node1 = headB if node1 is None else node1.next
-            node2 = headA if node2 is None else node2.next
-        return node1
-```
\ No newline at end of file
+    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
+        def get_length(head):
+            length = 0
+            while head:
+                length += 1
+                head = head.next
+            return length
+
+        # Get the lengths of both linked lists
+        lengthA = get_length(headA)
+        lengthB = get_length(headB)
+
+        # Align the starting points of both linked lists
+        while lengthA > lengthB:
+            headA = headA.next
+            lengthA -= 1
+        while lengthB > lengthA:
+            headB = headB.next
+            lengthB -= 1
+
+        # Traverse both lists together to find the intersection
+        while headA and headB:
+            if headA == headB:
+                return headA
+            headA = headA.next
+            headB = headB.next
+
+        return None
+```
+
+### Explanation:
+
+1. **Calculate the Lengths**:
+   - The `get_length` function calculates the length of a linked list by traversing it from the head to the end.
+   - We calculate `lengthA` for `headA` and `lengthB` for `headB`.
+
+2. **Align the Starting Points**:
+   - If `lengthA` is greater than `lengthB`, we advance `headA` by `lengthA - lengthB` steps.
+   - If `lengthB` is greater than `lengthA`, we advance `headB` by `lengthB - lengthA` steps.
+   - This ensures that both pointers are the same distance away from the potential intersection point.
+
+3. **Find the Intersection**:
+   - We traverse both lists simultaneously, comparing the nodes. If `headA` is equal to `headB`, we've found the intersection point and return it.
+   - If the traversal completes without finding an intersection, we return `None`.
+
+This approach ensures that we only traverse each list a maximum of twice (once to calculate lengths and once to find the intersection), making the solution efficient with O(n) time complexity and O(1) space complexity.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0169_majority_element/readme.md b/src/main/python/g0101_0200/s0169_majority_element/readme.md
index 6db9a30..049d422 100644
--- a/src/main/python/g0101_0200/s0169_majority_element/readme.md
+++ b/src/main/python/g0101_0200/s0169_majority_element/readme.md
@@ -29,32 +29,55 @@ The majority element is the element that appears more than `⌊n / 2⌋` times.
 
 **Follow-up:** Could you solve the problem in linear time and in `O(1)` space?
 
-## Solution
+To solve the problem of finding the majority element in an array in linear time and with O(1) space, we can use the **Boyer-Moore Voting Algorithm**. This algorithm is efficient and meets the requirements perfectly.
+
+### Steps:
+
+1. **Initialization**:
+   - Initialize two variables: `count` and `candidate`. The `count` is used to keep track of the number of occurrences of the current candidate for the majority element, and `candidate` stores the current candidate.
+
+2. **First Pass - Find a Candidate**:
+   - Traverse through the array and update the `candidate` and `count` based on the following rules:
+     - If `count` is 0, set the current element as the `candidate` and set `count` to 1.
+     - If the current element is the same as the `candidate`, increment the `count`.
+     - If the current element is different from the `candidate`, decrement the `count`.
+
+3. **Return the Candidate**:
+   - The element stored in `candidate` after the first pass will be the majority element, as guaranteed by the problem statement.
+
+### Implementation:
 
 ```python
 class Solution:
     def majorityElement(self, nums: List[int]) -> int:
-        count = 1
-        majority = arr[0]
-
-        # For Potential Majority Element
-        for i in range(1, len(arr)):
-            if arr[i] == majority:
+        candidate = None
+        count = 0
+        
+        for num in nums:
+            if count == 0:
+                candidate = num
+                count = 1
+            elif num == candidate:
                 count += 1
             else:
-                if count > 1:
-                    count -= 1
-                else:
-                    majority = arr[i]
+                count -= 1
+                
+        return candidate
+```
 
-        # For Confirmation
-        count = 0
-        for j in arr:
-            if j == majority:
-                count += 1
+### Explanation:
+
+1. **Initialization**:
+   - `candidate` is initialized to `None` and `count` to `0`.
+
+2. **First Pass - Find a Candidate**:
+   - Loop through each element in the array `nums`:
+     - If `count` is `0`, set the current element as the `candidate` and reset `count` to `1`.
+     - If the current element is the same as the `candidate`, increment `count`.
+     - If the current element is different from the `candidate`, decrement `count`.
+   - This process ensures that the `candidate` will be the element that appears more than `⌊n / 2⌋` times by the end of the loop.
+
+3. **Return the Candidate**:
+   - Return the `candidate` as the majority element.
 
-        if count >= (len(arr) // 2) + 1:
-            return majority
-        else:
-            return -1
-```
\ No newline at end of file
+This approach is efficient with a time complexity of O(n) and a space complexity of O(1), meeting the problem constraints.
\ No newline at end of file
diff --git a/src/main/python/g0101_0200/s0189_rotate_array/readme.md b/src/main/python/g0101_0200/s0189_rotate_array/readme.md
index 2755d5b..dafb695 100644
--- a/src/main/python/g0101_0200/s0189_rotate_array/readme.md
+++ b/src/main/python/g0101_0200/s0189_rotate_array/readme.md
@@ -41,23 +41,54 @@ Given an array, rotate the array to the right by `k` steps, where `k` is non-neg
 *   Try to come up with as many solutions as you can. There are at least **three** different ways to solve this problem.
 *   Could you do it in-place with `O(1)` extra space?
 
-## Solution
+To solve the problem and rotate the array to the right by `k` steps, we can use multiple approaches. One efficient way is to use array reversal. This approach requires O(1) extra space.
+
+### Steps:
+
+1. **Reverse the Entire Array**:
+   - Reverse the entire array.
+
+2. **Reverse the First `k` Elements**:
+   - Reverse the first `k` elements of the array.
+
+3. **Reverse the Remaining Elements**:
+   - Reverse the remaining elements of the array after the first `k` elements.
+
+### Implementation:
 
 ```python
 class Solution:
     def rotate(self, nums: List[int], k: int) -> None:
-        """
-        Do not return anything, modify nums in-place instead.
-        """
+        def reverse(arr, start, end):
+            while start < end:
+                arr[start], arr[end] = arr[end], arr[start]
+                start += 1
+                end -= 1
+
         n = len(nums)
-        t = n - (k % n)
-        self.reverse(nums, 0, t - 1)
-        self.reverse(nums, t, n - 1)
-        self.reverse(nums, 0, n - 1)
-
-    def reverse(self, nums: List[int], l: int, r: int) -> None:
-        while l <= r:
-            nums[l], nums[r] = nums[r], nums[l]
-            l += 1
-            r -= 1
-```
\ No newline at end of file
+        k %= n
+
+        # Reverse the entire array
+        reverse(nums, 0, n - 1)
+
+        # Reverse the first k elements
+        reverse(nums, 0, k - 1)
+
+        # Reverse the remaining elements
+        reverse(nums, k, n - 1)
+```
+
+### Explanation:
+
+1. **Reverse the Entire Array**:
+   - The `reverse` function is defined to reverse a portion of the array between indices `start` and `end`.
+   - We call `reverse(nums, 0, n - 1)` to reverse the entire array.
+
+2. **Reverse the First `k` Elements**:
+   - We calculate `k` as `k %= n` to handle cases where `k` is greater than the length of the array.
+   - We call `reverse(nums, 0, k - 1)` to reverse the first `k` elements of the array.
+
+3. **Reverse the Remaining Elements**:
+   - We call `reverse(nums, k, n - 1)` to reverse the remaining elements of the array after the first `k` elements.
+
+By following these steps, the array will be rotated to the right by `k` steps. This approach ensures that the rotation is done in-place with O(1) extra space and is efficient with a time complexity of O(n).
\ No newline at end of file
