From 298c7df330020a0d94abe9bfa1b0aea13e14a2a8 Mon Sep 17 00:00:00 2001 From: Roman Kurnovskii Date: Mon, 15 Dec 2025 09:47:21 +0200 Subject: [PATCH 1/2] upd --- explanations/237/en.md | 60 +++++++++++++++++++++++++++++++++ explanations/2482/en.md | 75 +++++++++++++++++++++++++++++++++++++++++ explanations/797/en.md | 68 +++++++++++++++++++++++++++++++++++++ solutions/1008/01.py | 29 ++++++++++++++++ solutions/1079/01.py | 16 +++++++++ solutions/1261/01.py | 28 +++++++++++++++ solutions/1326/01.py | 34 +++++++++++++++++++ solutions/1347/01.py | 13 +++++++ solutions/1551/01.py | 17 ++++++++++ solutions/1605/01.py | 14 ++++++++ solutions/1630/01.py | 25 ++++++++++++++ solutions/1823/01.py | 8 +++++ solutions/2120/01.py | 9 +++++ solutions/2221/01.py | 15 +++++++++ solutions/2326/01.py | 40 ++++++++++++++++++++++ solutions/237/01.py | 17 ++++++++++ solutions/2482/01.py | 23 +++++++++++++ solutions/2637/01.py | 12 +++++++ solutions/2785/01.py | 19 +++++++++++ solutions/797/01.py | 17 ++++++++++ 20 files changed, 539 insertions(+) create mode 100644 explanations/237/en.md create mode 100644 explanations/2482/en.md create mode 100644 explanations/797/en.md create mode 100644 solutions/1008/01.py create mode 100644 solutions/1079/01.py create mode 100644 solutions/1261/01.py create mode 100644 solutions/1326/01.py create mode 100644 solutions/1347/01.py create mode 100644 solutions/1551/01.py create mode 100644 solutions/1605/01.py create mode 100644 solutions/1630/01.py create mode 100644 solutions/1823/01.py create mode 100644 solutions/2120/01.py create mode 100644 solutions/2221/01.py create mode 100644 solutions/2326/01.py create mode 100644 solutions/237/01.py create mode 100644 solutions/2482/01.py create mode 100644 solutions/2637/01.py create mode 100644 solutions/2785/01.py create mode 100644 solutions/797/01.py diff --git a/explanations/237/en.md b/explanations/237/en.md new file mode 100644 index 0000000..c20a9ea --- /dev/null +++ b/explanations/237/en.md @@ -0,0 +1,60 @@ +## Explanation + +### Strategy + +**Restate the problem** + +We need to delete a node from a linked list, but we are only given access to the node to be deleted (not the head). We cannot access the previous node directly. + +**1.1 Constraints & Complexity** + +- **Input Size:** The linked list has 2 to 1000 nodes. +- **Time Complexity:** O(1) - We only perform a constant number of operations. +- **Space Complexity:** O(1) - No additional space is used. +- **Edge Case:** The node to delete is guaranteed not to be the tail node, so we can safely access node.next.next. + +**1.2 High-level approach** + +Since we cannot access the previous node, we cannot directly unlink the current node. Instead, we copy the value from the next node into the current node, then skip the next node by linking the current node to the node after the next one. + +![Linked list node deletion by copying value](https://assets.leetcode.com/uploads/2020/09/01/node1.jpg) + +**1.3 Brute force vs. optimized strategy** + +- **Brute Force:** If we had access to the head, we could traverse to find the previous node and update its next pointer. This would be O(n) time. +- **Optimized Strategy:** Copy the next node's value to the current node and skip the next node. This is O(1) time. +- **Why optimized is better:** We achieve constant time deletion by cleverly copying data instead of restructuring the list. + +**1.4 Decomposition** + +1. **Copy Value:** Copy the value from node.next to node. +2. **Skip Next Node:** Update node.next to point to node.next.next, effectively removing the next node from the list. + +### Steps + +**2.1 Initialization & Example Setup** + +Let's use the example: `head = [4,5,1,9]`, `node = 5` (the node with value 5) + +- The linked list: 4 → 5 → 1 → 9 +- We are given the node containing value 5 (second node) + +**2.2 Start Processing** + +We need to delete the node with value 5. Since we only have access to this node, we cannot modify the previous node (4). + +**2.3 Trace Walkthrough** + +| Step | Current Node Value | Next Node Value | Action | Result | +|------|-------------------|-----------------|--------|--------| +| Initial | 5 | 1 | - | 4 → 5 → 1 → 9 | +| Copy | 5 → 1 | 1 | Copy next value | 4 → 1 → 1 → 9 | +| Skip | 1 | 9 | Link to next.next | 4 → 1 → 9 | + +**2.4 Update Pointers** + +After copying the value, we update `node.next = node.next.next`, which removes the duplicate node from the list. + +**2.5 Return Result** + +The list becomes `[4,1,9]`, effectively deleting the original node with value 5. Note that we actually deleted the next node, but from the user's perspective, the node with value 5 is gone. diff --git a/explanations/2482/en.md b/explanations/2482/en.md new file mode 100644 index 0000000..5273665 --- /dev/null +++ b/explanations/2482/en.md @@ -0,0 +1,75 @@ +## Explanation + +### Strategy + +**Restate the problem** + +We are given a binary matrix and need to create a difference matrix where each cell `diff[i][j]` is calculated as: ones in row i + ones in column j - zeros in row i - zeros in column j. + +**1.1 Constraints & Complexity** + +- **Input Size:** The matrix can have up to 10^5 rows and columns, with total cells up to 10^5. +- **Time Complexity:** O(m*n) - We need to traverse the matrix twice: once to count ones in rows and columns, and once to build the result matrix. +- **Space Complexity:** O(m + n) - We store arrays for row and column counts. +- **Edge Case:** Empty matrix or single cell matrix are handled naturally by the algorithm. + +**1.2 High-level approach** + +The goal is to compute the difference matrix efficiently by precomputing row and column statistics. Instead of recalculating counts for each cell, we count ones in each row and column once, then use these counts to compute each cell's value. + +![Matrix showing row and column counts with difference calculation](https://assets.leetcode.com/uploads/2022/11/06/image-20221106171729-5.png) + +**1.3 Brute force vs. optimized strategy** + +- **Brute Force:** For each cell (i, j), count ones and zeros in row i and column j separately. This results in O(m*n*(m+n)) time complexity, which is inefficient. +- **Optimized Strategy:** Precompute ones count for all rows and columns in O(m*n) time, then compute each cell in O(1) time using the precomputed values. Total time is O(m*n). +- **Why optimized is better:** We avoid redundant calculations by reusing row and column statistics across all cells in the same row or column. + +**1.4 Decomposition** + +1. **Count Row Statistics:** Traverse the matrix once to count the number of ones in each row. +2. **Count Column Statistics:** During the same traversal, count the number of ones in each column. +3. **Calculate Zeros:** For each row, zeros = total columns - ones. For each column, zeros = total rows - ones. +4. **Build Result Matrix:** For each cell (i, j), compute diff[i][j] = ones_row[i] + ones_col[j] - zeros_row[i] - zeros_col[j]. + +### Steps + +**2.1 Initialization & Example Setup** + +Let's use the example: `grid = [[0,1,1],[1,0,1],[0,0,1]]` + +- Matrix dimensions: 3 rows × 3 columns +- Initialize `ones_row = [0, 0, 0]` and `ones_col = [0, 0, 0]` + +**2.2 Start Counting** + +Traverse the matrix to count ones: +- Row 0: [0,1,1] → ones_row[0] = 2 +- Row 1: [1,0,1] → ones_row[1] = 2 +- Row 2: [0,0,1] → ones_row[2] = 1 + +- Column 0: [0,1,0] → ones_col[0] = 1 +- Column 1: [1,0,0] → ones_col[1] = 1 +- Column 2: [1,1,1] → ones_col[2] = 3 + +**2.3 Trace Walkthrough** + +| Cell (i,j) | ones_row[i] | ones_col[j] | zeros_row[i] | zeros_col[j] | diff[i][j] | +|------------|-------------|-------------|--------------|--------------|------------| +| (0,0) | 2 | 1 | 1 | 2 | 2+1-1-2 = 0 | +| (0,1) | 2 | 1 | 1 | 2 | 2+1-1-2 = 0 | +| (0,2) | 2 | 3 | 1 | 0 | 2+3-1-0 = 4 | +| (1,0) | 2 | 1 | 1 | 2 | 2+1-1-2 = 0 | +| (1,1) | 2 | 1 | 1 | 2 | 2+1-1-2 = 0 | +| (1,2) | 2 | 3 | 1 | 0 | 2+3-1-0 = 4 | +| (2,0) | 1 | 1 | 2 | 2 | 1+1-2-2 = -2 | +| (2,1) | 1 | 1 | 2 | 2 | 1+1-2-2 = -2 | +| (2,2) | 1 | 3 | 2 | 0 | 1+3-2-0 = 2 | + +**2.4 Build Result** + +Create result matrix `res` with dimensions 3×3 and fill each cell using the formula. + +**2.5 Return Result** + +Return `[[0,0,4],[0,0,4],[-2,-2,2]]`, which matches the expected output. diff --git a/explanations/797/en.md b/explanations/797/en.md new file mode 100644 index 0000000..2f3db91 --- /dev/null +++ b/explanations/797/en.md @@ -0,0 +1,68 @@ +## Explanation + +### Strategy + +**Restate the problem** + +We need to find all paths from node 0 to node n-1 in a directed acyclic graph (DAG). Each path is a sequence of nodes connected by edges. + +**1.1 Constraints & Complexity** + +- **Input Size:** The graph has 2 to 15 nodes. +- **Time Complexity:** O(2^n * n) - In the worst case, there can be exponentially many paths, and each path can have up to n nodes. +- **Space Complexity:** O(2^n * n) - We need to store all paths, and the recursion stack can go up to n levels. +- **Edge Case:** If there are no paths from 0 to n-1, we return an empty list. + +**1.2 High-level approach** + +Use depth-first search (DFS) to explore all possible paths from the source node (0) to the target node (n-1). As we traverse, we maintain the current path and add it to results when we reach the destination. + +![Graph showing all paths from source to target](https://assets.leetcode.com/uploads/2020/09/28/all_1.jpg) + +**1.3 Brute force vs. optimized strategy** + +- **Brute Force:** Generate all possible paths and filter those that end at n-1. This is inefficient and doesn't leverage the DAG structure. +- **Optimized Strategy:** Use DFS with backtracking to explore paths incrementally, only following edges that can potentially lead to the target. This naturally finds all valid paths. +- **Why optimized is better:** DFS with backtracking efficiently explores the graph structure without redundant computations, and backtracking allows us to reuse the path list. + +**1.4 Decomposition** + +1. **Initialize Result:** Create an empty list to store all paths. +2. **Start DFS:** Begin DFS from node 0 with an initial path containing just node 0. +3. **Explore Neighbors:** For each neighbor of the current node, add it to the path and recursively explore. +4. **Record Complete Paths:** When we reach node n-1, add the current path to results. +5. **Backtrack:** After exploring a neighbor, remove it from the path to try other paths. + +### Steps + +**2.1 Initialization & Example Setup** + +Let's use the example: `graph = [[1,2],[3],[3],[]]` + +- Nodes: 0, 1, 2, 3 +- Edges: 0→1, 0→2, 1→3, 2→3 +- Target: node 3 + +**2.2 Start DFS** + +Initialize `res = []` and start DFS from node 0 with `path = [0]`. + +**2.3 Trace Walkthrough** + +| Current Node | Path | Neighbors | Action | Result | +|-------------|------|-----------|--------|--------| +| 0 | [0] | [1,2] | Explore 1 | - | +| 1 | [0,1] | [3] | Explore 3 | - | +| 3 | [0,1,3] | [] | Reached target! | Add [0,1,3] | +| 1 | [0,1] | [3] | Backtrack | - | +| 0 | [0] | [1,2] | Explore 2 | - | +| 2 | [0,2] | [3] | Explore 3 | - | +| 3 | [0,2,3] | [] | Reached target! | Add [0,2,3] | + +**2.4 Backtrack and Continue** + +After finding path [0,1,3], we backtrack by removing 3 and 1 from the path, returning to node 0. Then we explore the other neighbor (2) to find [0,2,3]. + +**2.5 Return Result** + +After DFS completes, `res = [[0,1,3],[0,2,3]]`, which contains all paths from node 0 to node 3. diff --git a/solutions/1008/01.py b/solutions/1008/01.py new file mode 100644 index 0000000..708fa36 --- /dev/null +++ b/solutions/1008/01.py @@ -0,0 +1,29 @@ +# 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 bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]: + if not preorder: + return None + + root = TreeNode(preorder[0]) + stack = [root] + + for val in preorder[1:]: + node = TreeNode(val) + + # If current value is less than stack top, it's left child + if val < stack[-1].val: + stack[-1].left = node + else: + # Find the parent where this node should be right child + while stack and stack[-1].val < val: + parent = stack.pop() + parent.right = node + + stack.append(node) + + return root diff --git a/solutions/1079/01.py b/solutions/1079/01.py new file mode 100644 index 0000000..88c89e1 --- /dev/null +++ b/solutions/1079/01.py @@ -0,0 +1,16 @@ +class Solution: + def numTilePossibilities(self, tiles: str) -> int: + from collections import Counter + + def backtrack(count): + res = 0 + for char in count: + if count[char] > 0: + res += 1 # Count this sequence + count[char] -= 1 + res += backtrack(count) # Continue building + count[char] += 1 # Backtrack + return res + + count = Counter(tiles) + return backtrack(count) diff --git a/solutions/1261/01.py b/solutions/1261/01.py new file mode 100644 index 0000000..19ad1df --- /dev/null +++ b/solutions/1261/01.py @@ -0,0 +1,28 @@ +# 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 FindElements: + + def __init__(self, root: Optional[TreeNode]): + self.values = set() + + def recover(node, val): + if not node: + return + node.val = val + self.values.add(val) + recover(node.left, 2 * val + 1) + recover(node.right, 2 * val + 2) + + recover(root, 0) + + def find(self, target: int) -> bool: + return target in self.values + + +# Your FindElements object will be instantiated and called as such: +# obj = FindElements(root) +# param_1 = obj.find(target) diff --git a/solutions/1326/01.py b/solutions/1326/01.py new file mode 100644 index 0000000..0e30397 --- /dev/null +++ b/solutions/1326/01.py @@ -0,0 +1,34 @@ +class Solution: + def minTaps(self, n: int, ranges: List[int]) -> int: + # Create intervals + intervals = [] + for i in range(n + 1): + if ranges[i] > 0: + left = max(0, i - ranges[i]) + right = min(n, i + ranges[i]) + intervals.append((left, right)) + + if not intervals: + return -1 + + # Sort by left endpoint + intervals.sort() + + res = 0 + covered = 0 + i = 0 + + while covered < n: + max_right = covered + # Find interval that starts <= covered and extends farthest + while i < len(intervals) and intervals[i][0] <= covered: + max_right = max(max_right, intervals[i][1]) + i += 1 + + if max_right == covered: + return -1 # Cannot extend coverage + + covered = max_right + res += 1 + + return res diff --git a/solutions/1347/01.py b/solutions/1347/01.py new file mode 100644 index 0000000..bcb0551 --- /dev/null +++ b/solutions/1347/01.py @@ -0,0 +1,13 @@ +class Solution: + def minSteps(self, s: str, t: str) -> int: + from collections import Counter + + count_s = Counter(s) + count_t = Counter(t) + + res = 0 + for char in count_s: + if count_s[char] > count_t[char]: + res += count_s[char] - count_t[char] + + return res diff --git a/solutions/1551/01.py b/solutions/1551/01.py new file mode 100644 index 0000000..da1f22f --- /dev/null +++ b/solutions/1551/01.py @@ -0,0 +1,17 @@ +class Solution: + def findMinFibonacciNumbers(self, k: int) -> int: + # Generate Fibonacci numbers up to k + fib = [1, 1] + while fib[-1] < k: + fib.append(fib[-1] + fib[-2]) + + # Greedy: use largest Fibonacci number <= remaining k + res = 0 + idx = len(fib) - 1 + while k > 0: + while fib[idx] > k: + idx -= 1 + k -= fib[idx] + res += 1 + + return res diff --git a/solutions/1605/01.py b/solutions/1605/01.py new file mode 100644 index 0000000..4e4ee73 --- /dev/null +++ b/solutions/1605/01.py @@ -0,0 +1,14 @@ +class Solution: + def restoreMatrix(self, rowSum: List[int], colSum: List[int]) -> List[List[int]]: + m, n = len(rowSum), len(colSum) + res = [[0] * n for _ in range(m)] + + for i in range(m): + for j in range(n): + # Place minimum of remaining row sum and column sum + val = min(rowSum[i], colSum[j]) + res[i][j] = val + rowSum[i] -= val + colSum[j] -= val + + return res diff --git a/solutions/1630/01.py b/solutions/1630/01.py new file mode 100644 index 0000000..0aad93a --- /dev/null +++ b/solutions/1630/01.py @@ -0,0 +1,25 @@ +class Solution: + def checkArithmeticSubarrays( + self, nums: List[int], l: List[int], r: List[int] + ) -> List[bool]: + res = [] + + for i in range(len(l)): + subarray = nums[l[i] : r[i] + 1] + subarray.sort() + + if len(subarray) < 2: + res.append(True) + continue + + diff = subarray[1] - subarray[0] + is_arithmetic = True + + for j in range(1, len(subarray)): + if subarray[j] - subarray[j - 1] != diff: + is_arithmetic = False + break + + res.append(is_arithmetic) + + return res diff --git a/solutions/1823/01.py b/solutions/1823/01.py new file mode 100644 index 0000000..02eacdc --- /dev/null +++ b/solutions/1823/01.py @@ -0,0 +1,8 @@ +class Solution: + def findTheWinner(self, n: int, k: int) -> int: + # Josephus problem + # Use 0-indexed, then convert to 1-indexed at the end + res = 0 + for i in range(2, n + 1): + res = (res + k) % i + return res + 1 diff --git a/solutions/2120/01.py b/solutions/2120/01.py new file mode 100644 index 0000000..8997322 --- /dev/null +++ b/solutions/2120/01.py @@ -0,0 +1,9 @@ +class Solution: + def sumOfThree(self, num: int) -> List[int]: + # If num = (x-1) + x + (x+1) = 3x + # Then x = num / 3 + if num % 3 != 0: + return [] + + x = num // 3 + return [x - 1, x, x + 1] diff --git a/solutions/2221/01.py b/solutions/2221/01.py new file mode 100644 index 0000000..fbcd23d --- /dev/null +++ b/solutions/2221/01.py @@ -0,0 +1,15 @@ +class Solution: + def findChampion(self, grid: List[List[int]]) -> int: + n = len(grid) + + # Find team that beats all others (row has all 1s except diagonal) + for i in range(n): + is_champion = True + for j in range(n): + if i != j and grid[i][j] == 0: + is_champion = False + break + if is_champion: + return i + + return -1 diff --git a/solutions/2326/01.py b/solutions/2326/01.py new file mode 100644 index 0000000..b1dd03d --- /dev/null +++ b/solutions/2326/01.py @@ -0,0 +1,40 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def spiralMatrix(self, m: int, n: int, head: Optional[ListNode]) -> List[List[int]]: + # Initialize matrix with -1 + res = [[-1] * n for _ in range(m)] + + # Directions: right, down, left, up + directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] + dir_idx = 0 + row, col = 0, 0 + + current = head + while current: + res[row][col] = current.val + current = current.next + + # Calculate next position + dr, dc = directions[dir_idx] + next_row, next_col = row + dr, col + dc + + # Check if we need to change direction + if ( + next_row < 0 + or next_row >= m + or next_col < 0 + or next_col >= n + or res[next_row][next_col] != -1 + ): + # Change direction + dir_idx = (dir_idx + 1) % 4 + dr, dc = directions[dir_idx] + next_row, next_col = row + dr, col + dc + + row, col = next_row, next_col + + return res diff --git a/solutions/237/01.py b/solutions/237/01.py new file mode 100644 index 0000000..b17ab48 --- /dev/null +++ b/solutions/237/01.py @@ -0,0 +1,17 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + + +class Solution: + def deleteNode(self, node): + """ + :type node: ListNode + :rtype: void Do not return anything, modify node in-place instead. + """ + # Copy next node's value to current node + node.val = node.next.val + # Skip the next node + node.next = node.next.next diff --git a/solutions/2482/01.py b/solutions/2482/01.py new file mode 100644 index 0000000..24927b9 --- /dev/null +++ b/solutions/2482/01.py @@ -0,0 +1,23 @@ +class Solution: + def onesMinusZeros(self, grid: List[List[int]]) -> List[List[int]]: + m, n = len(grid), len(grid[0]) + + # Count ones in each row and column + ones_row = [0] * m + ones_col = [0] * n + + for i in range(m): + for j in range(n): + if grid[i][j] == 1: + ones_row[i] += 1 + ones_col[j] += 1 + + # Build result matrix + res = [[0] * n for _ in range(m)] + for i in range(m): + for j in range(n): + zeros_row = n - ones_row[i] + zeros_col = m - ones_col[j] + res[i][j] = ones_row[i] + ones_col[j] - zeros_row - zeros_col + + return res diff --git a/solutions/2637/01.py b/solutions/2637/01.py new file mode 100644 index 0000000..a24f828 --- /dev/null +++ b/solutions/2637/01.py @@ -0,0 +1,12 @@ +class Solution: + def rowAndMaximumOnes(self, mat: List[List[int]]) -> List[int]: + max_ones = -1 + max_row = 0 + + for i, row in enumerate(mat): + ones_count = sum(row) + if ones_count > max_ones: + max_ones = ones_count + max_row = i + + return [max_row, max_ones] diff --git a/solutions/2785/01.py b/solutions/2785/01.py new file mode 100644 index 0000000..c08db60 --- /dev/null +++ b/solutions/2785/01.py @@ -0,0 +1,19 @@ +class Solution: + def sortVowels(self, s: str) -> str: + vowels = {"a", "e", "i", "o", "u", "A", "E", "I", "O", "U"} + + # Extract and sort vowels + vowel_list = [char for char in s if char in vowels] + vowel_list.sort() + + # Build result + res = [] + vowel_idx = 0 + for char in s: + if char in vowels: + res.append(vowel_list[vowel_idx]) + vowel_idx += 1 + else: + res.append(char) + + return "".join(res) diff --git a/solutions/797/01.py b/solutions/797/01.py new file mode 100644 index 0000000..68433e3 --- /dev/null +++ b/solutions/797/01.py @@ -0,0 +1,17 @@ +class Solution: + def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]: + res = [] + n = len(graph) + + def dfs(node, path): + if node == n - 1: + res.append(path[:]) + return + + for neighbor in graph[node]: + path.append(neighbor) + dfs(neighbor, path) + path.pop() + + dfs(0, [0]) + return res From 3a99b0c31abd8e756606489fb1027fc70e7dcdcf Mon Sep 17 00:00:00 2001 From: Roman Kurnovskii Date: Mon, 15 Dec 2025 11:41:25 +0200 Subject: [PATCH 2/2] solutions + exlnations --- data/leetcode-problems.json | 18 ++++++++++++- explanations/1008/en.md | 52 ++++++++++++++++++++++++++++++++++++ explanations/1079/en.md | 50 ++++++++++++++++++++++++++++++++++ explanations/1261/en.md | 48 +++++++++++++++++++++++++++++++++ explanations/1347/en.md | 53 +++++++++++++++++++++++++++++++++++++ explanations/1551/en.md | 46 ++++++++++++++++++++++++++++++++ explanations/1605/en.md | 51 +++++++++++++++++++++++++++++++++++ explanations/1630/en.md | 47 ++++++++++++++++++++++++++++++++ explanations/1823/en.md | 48 +++++++++++++++++++++++++++++++++ explanations/2110/en.md | 50 ++++++++++++++++++++++++++++++++++ explanations/2120/en.md | 51 +++++++++++++++++++++++++++++++++++ explanations/2221/en.md | 53 +++++++++++++++++++++++++++++++++++++ explanations/2326/en.md | 49 ++++++++++++++++++++++++++++++++++ explanations/237/en.md | 45 +++++++++++++++++++++++++++++++ explanations/2482/en.md | 48 +++++++++++++++++++++++++++++++++ explanations/2785/en.md | 53 +++++++++++++++++++++++++++++++++++++ explanations/797/en.md | 48 +++++++++++++++++++++++++++++++++ solutions/1008/01.py | 14 +++++----- solutions/1079/01.py | 26 ++++++++++-------- solutions/1261/01.py | 23 +++++++--------- solutions/1347/01.py | 11 ++++---- solutions/1551/01.py | 26 +++++++++--------- solutions/1605/01.py | 8 +++--- solutions/1630/01.py | 41 ++++++++++++++-------------- solutions/1823/01.py | 11 ++++---- solutions/2110/01.py | 22 +++++++++++++++ solutions/2120/01.py | 40 ++++++++++++++++++++++------ solutions/2221/01.py | 23 +++++++--------- solutions/2326/01.py | 39 +++++++++++++-------------- solutions/237/01.py | 5 ++-- solutions/2482/01.py | 29 +++++++++++--------- solutions/2637/01.py | 14 +++++----- solutions/2785/01.py | 20 +++++++------- solutions/3271/01.py | 10 +++++++ solutions/797/01.py | 8 +++--- 35 files changed, 1025 insertions(+), 155 deletions(-) create mode 100644 explanations/1008/en.md create mode 100644 explanations/1079/en.md create mode 100644 explanations/1261/en.md create mode 100644 explanations/1347/en.md create mode 100644 explanations/1551/en.md create mode 100644 explanations/1605/en.md create mode 100644 explanations/1630/en.md create mode 100644 explanations/1823/en.md create mode 100644 explanations/2110/en.md create mode 100644 explanations/2120/en.md create mode 100644 explanations/2221/en.md create mode 100644 explanations/2326/en.md create mode 100644 explanations/2785/en.md create mode 100644 solutions/2110/01.py create mode 100644 solutions/3271/01.py diff --git a/data/leetcode-problems.json b/data/leetcode-problems.json index 8b6e577..1aaa252 100644 --- a/data/leetcode-problems.json +++ b/data/leetcode-problems.json @@ -25823,5 +25823,21 @@ "id": 3772, "link": "https://leetcode.com/problems/maximum-subgraph-score-in-a-tree/", "title": "Maximum Subgraph Score in a Tree" - } + }, + "797": {"id": 797, "category": "Graph", "title": "All Paths From Source to Target", "difficulty": "Medium", "link": "https://leetcode.com/problems/all-paths-from-source-to-target/", "tags": []}, + "1008": {"id": 1008, "category": "Tree", "title": "Construct Binary Search Tree from Preorder Traversal", "difficulty": "Medium", "link": "https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/", "tags": []}, + "1079": {"id": 1079, "category": "Backtracking", "title": "Letter Tile Possibilities", "difficulty": "Medium", "link": "https://leetcode.com/problems/letter-tile-possibilities/", "tags": []}, + "1261": {"id": 1261, "category": "Tree", "title": "Find Elements in a Contaminated Binary Tree", "difficulty": "Medium", "link": "https://leetcode.com/problems/find-elements-in-a-contaminated-binary-tree/", "tags": []}, + "1630": {"id": 1630, "category": "Array", "title": "Arithmetic Subarrays", "difficulty": "Medium", "link": "https://leetcode.com/problems/arithmetic-subarrays/", "tags": []}, + "2110": {"id": 2110, "category": "Array", "title": "Number of Smooth Descent Periods of a Stock", "difficulty": "Medium", "link": "https://leetcode.com/problems/number-of-smooth-descent-periods-of-a-stock/", "tags": []}, + "237": {"id": 237, "category": "Linked List", "title": "Delete Node in a Linked List", "difficulty": "Medium", "link": "https://leetcode.com/problems/delete-node-in-a-linked-list/", "tags": []}, + "2482": {"id": 2482, "category": "Matrix", "title": "Difference Between Ones and Zeros in Row and Column", "difficulty": "Medium", "link": "https://leetcode.com/problems/difference-between-ones-and-zeros-in-row-and-column/", "tags": []}, + "2785": {"id": 2785, "category": "String", "title": "Sort Vowels in a String", "difficulty": "Medium", "link": "https://leetcode.com/problems/sort-vowels-in-a-string/", "tags": []}, + "1347": {"id": 1347, "category": "String", "title": "Minimum Number of Steps to Make Two Strings Anagram", "difficulty": "Medium", "link": "https://leetcode.com/problems/minimum-number-of-steps-to-make-two-strings-anagram/", "tags": []}, + "2326": {"id": 2326, "category": "Matrix", "title": "Spiral Matrix IV", "difficulty": "Medium", "link": "https://leetcode.com/problems/spiral-matrix-iv/", "tags": []}, + "1823": {"id": 1823, "category": "Math", "title": "Find the Winner of the Circular Game", "difficulty": "Medium", "link": "https://leetcode.com/problems/find-the-winner-of-the-circular-game/", "tags": []}, + "2120": {"id": 2120, "category": "Simulation", "title": "Execution of All Suffix Instructions Staying in a Grid", "difficulty": "Medium", "link": "https://leetcode.com/problems/execution-of-all-suffix-instructions-staying-in-a-grid/", "tags": []}, + "2221": {"id": 2221, "category": "Array", "title": "Find Triangular Sum of an Array", "difficulty": "Medium", "link": "https://leetcode.com/problems/find-triangular-sum-of-an-array/", "tags": []}, + "1605": {"id": 1605, "category": "Matrix", "title": "Find Valid Matrix Given Row and Column Sums", "difficulty": "Medium", "link": "https://leetcode.com/problems/find-valid-matrix-given-row-and-column-sums/", "tags": []}, + "1551": {"id": 1551, "category": "Math", "title": "Minimum Operations to Make Array Equal", "difficulty": "Medium", "link": "https://leetcode.com/problems/minimum-operations-to-make-array-equal/", "tags": []} } diff --git a/explanations/1008/en.md b/explanations/1008/en.md new file mode 100644 index 0000000..b502b4b --- /dev/null +++ b/explanations/1008/en.md @@ -0,0 +1,52 @@ +## Explanation + +### Strategy + +**Restate the problem** +Given preorder traversal of a BST, reconstruct the tree. + +**1.1 Constraints & Complexity** +- **Input Size:** up to 100 nodes. +- **Time Complexity:** O(n) using a stack to place nodes. +- **Space Complexity:** O(n) for the stack/tree nodes. +- **Edge Case:** Single-node preorder list. + +**1.2 High-level approach** +Iterate preorder; use a stack of ancestors. Each value smaller than stack top goes left; otherwise pop until finding parent, then attach right. +![BST reconstruction from preorder](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Insert each value via BST insert — still O(n²) worst case (sorted input). +- **Optimized:** Monotonic stack to place nodes in O(n). + +**1.4 Decomposition** +1. Create root from first value; push to stack. +2. For each next value: + - If value < stack top, set as left child of top. + - Else pop until stack empty or top > value; last popped is parent; attach as right child. +3. Push new node to stack. +4. Return root. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `[8,5,1,7,10,12]`; root = 8, stack = [8]. + +**2.2 Start Checking** +Process each value, updating stack and children. + +**2.3 Trace Walkthrough** +| val | Stack before | Action | Child | +|-----|--------------|---------------------------------|--------| +| 5 | [8] | 5 < 8 → left of 8 | left | +| 1 | [8,5] | 1 < 5 → left of 5 | left | +| 7 | [8,5,1] | pop 1,5 (last popped=5) → right | right | +| 10 | [8,7] | pop 7,8 (last popped=8) → right | right | +| 12 | [10] | pop none → right of 10 | right | + +**2.4 Increment and Loop** +Continue until all preorder values are attached. + +**2.5 Return Result** +Root of the constructed BST. + diff --git a/explanations/1079/en.md b/explanations/1079/en.md new file mode 100644 index 0000000..28819c5 --- /dev/null +++ b/explanations/1079/en.md @@ -0,0 +1,50 @@ +## Explanation + +### Strategy + +**Restate the problem** +Count all non-empty sequences that can be formed from the multiset of tiles (letters), respecting available counts. + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= len(tiles) <= 7`. +- **Time Complexity:** O(n! * n) in worst case (backtracking over permutations), acceptable for n <= 7. +- **Space Complexity:** O(n) recursion depth + O(1) counts. +- **Edge Case:** Single tile → exactly 1 sequence. + +**1.2 High-level approach** +Use backtracking with frequency counts; at each step, pick a letter with remaining count, decrement, recurse, then restore. +![Backtracking over letter counts](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Generate all permutations with duplicates and then deduplicate — costly. +- **Optimized:** Use counts to avoid generating identical branches; count as we go. + +**1.4 Decomposition** +1. Build frequency map of letters. +2. DFS: for each letter with count > 0, use it (res++), decrement, recurse, restore. +3. Sum all counts encountered. +4. Return `res`. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `tiles = "AAB"`; counts: A:2, B:1, `res=0`. + +**2.2 Start Checking** +Try each available letter, recurse with updated counts. + +**2.3 Trace Walkthrough** +| Path | Counts after pick | res increment | Notes | +|---------|-------------------|---------------|--------------| +| A | A:1,B:1 | +1 | recurse more | +| AA | A:0,B:1 | +1 | recurse | +| AAB | A:0,B:0 | +1 | dead end | +| AB | A:1,B:0 | +1 | recurse | +| ... | ... | ... | ... | + +**2.4 Increment and Loop** +Each pick adds 1 to `res` (for the new sequence) before deeper recursion. + +**2.5 Return Result** +Final `res = 8` for the example. + diff --git a/explanations/1261/en.md b/explanations/1261/en.md new file mode 100644 index 0000000..165aa16 --- /dev/null +++ b/explanations/1261/en.md @@ -0,0 +1,48 @@ +## Explanation + +### Strategy + +**Restate the problem** +Recover a contaminated binary tree where original root was 0 and children follow `left = 2*x+1`, `right = 2*x+2`. Support queries to check if a target value exists. + +**1.1 Constraints & Complexity** +- **Input Size:** Up to `1e4` nodes, height <= 20. +- **Time Complexity:** O(n) to recover; O(1) average for `find` via set lookup. +- **Space Complexity:** O(n) to store recovered values. +- **Edge Case:** Single-node tree. + +**1.2 High-level approach** +DFS from root, assign values by the given formulas, store all in a hash set for O(1) membership. +![Tree recovery with value formulas](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Recover on every `find`, re-walking the tree — repeated O(n). +- **Optimized:** Recover once, store in a set — O(n) build, O(1) queries. + +**1.4 Decomposition** +1. DFS from root with value parameter. +2. Assign `val`, insert into set. +3. Recurse to children with `2*val+1` and `2*val+2`. +4. `find` checks membership in the set. + +### Steps + +**2.1 Initialization & Example Setup** +Start at root with value 0, empty set. + +**2.2 Start Processing** +DFS visits each node, computing and storing values. + +**2.3 Trace Walkthrough** +| Node | Assigned val | Action | +|------|--------------|---------------| +| root | 0 | add to set | +| left | 1 | add to set | +| right| 2 | add to set | + +**2.4 Increment and Loop** +Continue recursively; each node’s children follow the formula. + +**2.5 Return Result** +`find(target)` returns `target in set`. + diff --git a/explanations/1347/en.md b/explanations/1347/en.md new file mode 100644 index 0000000..61e8b53 --- /dev/null +++ b/explanations/1347/en.md @@ -0,0 +1,53 @@ +## Explanation + +### Strategy + +**Restate the problem** +Given two equal-length lowercase strings `s` and `t`, find the minimum number of character replacements in `t` to make it an anagram of `s`. + +**1.1 Constraints & Complexity** +- **Input Size:** up to 5×10^4 characters. +- **Time Complexity:** O(n) to count frequencies. +- **Space Complexity:** O(1) since alphabet size is fixed (26). +- **Edge Case:** Already anagrams → 0 steps. + +**1.2 High-level approach** +Count letters in both strings; for each character, if `s` needs more than `t` has, that deficit contributes to the answer. +![Frequency gap guiding replacements](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Try all replacement combinations — exponential. +- **Optimized:** Frequency difference — O(n), straightforward. + +**1.4 Decomposition** +1. Count frequencies of `s` and `t`. +2. For each letter, compute `max(0, count_s - count_t)` and sum. +3. That sum is the number of replacements needed in `t`. +4. Return the sum. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `s="leetcode"`, `t="practice"`. + +**2.2 Start Checking** +Build `count_s`, `count_t`. + +**2.3 Trace Walkthrough** +| Char | count_s | count_t | deficit (if s needs more) | +|------|---------|---------|----------------------------| +| e | 3 | 1 | +2 | +| l | 1 | 0 | +1 | +| t | 1 | 1 | 0 | +| c | 1 | 2 | 0 | +| o | 1 | 0 | +1 | +| d | 1 | 0 | +1 | +| ... | ... | ... | ... | +Total = 5. + +**2.4 Increment and Loop** +Sum deficits over all 26 letters. + +**2.5 Return Result** +Return the total replacements (5 in the example). + diff --git a/explanations/1551/en.md b/explanations/1551/en.md new file mode 100644 index 0000000..4c0aec1 --- /dev/null +++ b/explanations/1551/en.md @@ -0,0 +1,46 @@ +## Explanation + +### Strategy + +**Restate the problem** +Array is `[1,3,5,...,2n-1]`; in one operation, decrement one element and increment another. Find min operations to make all elements equal. + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= n <= 1e4`. +- **Time Complexity:** O(n) to sum needed moves. +- **Space Complexity:** O(1). +- **Edge Case:** n=1 → 0 operations. + +**1.2 High-level approach** +Target value is `n` (the average). Pair symmetric elements; each pair needs `(target - current_lower)` moves. Sum over first half. +![Balancing around the center value](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Simulate operations — inefficient. +- **Optimized:** Direct formula using symmetry — O(n). + +**1.4 Decomposition** +1. Target = n. +2. For i in [0 .. n/2 - 1], current = 2*i+1. +3. Add `target - current` to result. +4. Return result. + +### Steps + +**2.1 Initialization & Example Setup** +Example: n=3; array [1,3,5], target=3. + +**2.2 Start Checking** +Only i=0 in first half: current=1 → need 2 moves. + +**2.3 Trace Walkthrough** +| i | current | target | add to res | +|---|---------|--------|------------| +| 0 | 1 | 3 | 2 | + +**2.4 Increment and Loop** +Loop over first half (integer division). + +**2.5 Return Result** +Return accumulated moves (2 for n=3). + diff --git a/explanations/1605/en.md b/explanations/1605/en.md new file mode 100644 index 0000000..12a947f --- /dev/null +++ b/explanations/1605/en.md @@ -0,0 +1,51 @@ +## Explanation + +### Strategy + +**Restate the problem** +Construct a non-negative matrix that matches given row sums and column sums. + +**1.1 Constraints & Complexity** +- **Input Size:** up to 500 rows/cols. +- **Time Complexity:** O(m*n) greedy fill. +- **Space Complexity:** O(m*n) for the output matrix. +- **Edge Case:** Trivial 1x1 matrix equals the shared sum. + +**1.2 High-level approach** +Greedy: at cell (i,j), place `min(rowSum[i], colSum[j])`, then decrement both sums; proceed row by row. +![Greedy fill consuming row/col budgets](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Search all matrices satisfying sums — exponential. +- **Optimized:** Greedy works because any feasible solution can allocate the minimal remaining budget without violating totals. + +**1.4 Decomposition** +1. Initialize `res` with zeros. +2. For each cell `(i,j)`: + - `val = min(rowSum[i], colSum[j])` + - Set `res[i][j] = val`, update rowSum/colSum. +3. Continue until all cells processed. +4. Return `res`. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `rowSum=[3,8]`, `colSum=[4,7]`, res all zeros. + +**2.2 Start Checking** +At (0,0): min(3,4)=3 → res[0][0]=3; rowSum=[0,8], colSum=[1,7]. + +**2.3 Trace Walkthrough** +| Cell | rowSum before | colSum before | placed | rowSum after | colSum after | +|------|---------------|---------------|--------|--------------|--------------| +| (0,0)| 3 | 4 | 3 | 0 | 1 | +| (0,1)| 0 | 7 | 0 | 0 | 7 | +| (1,0)| 8 | 1 | 1 | 7 | 0 | +| (1,1)| 7 | 7 | 7 | 0 | 0 | + +**2.4 Increment and Loop** +Proceed left-to-right, top-to-bottom. + +**2.5 Return Result** +Matrix satisfies all row/column sums. + diff --git a/explanations/1630/en.md b/explanations/1630/en.md new file mode 100644 index 0000000..e4b5da6 --- /dev/null +++ b/explanations/1630/en.md @@ -0,0 +1,47 @@ +## Explanation + +### Strategy + +**Restate the problem** +For each query `[l_i, r_i]`, decide if the subarray can be rearranged into an arithmetic progression. + +**1.1 Constraints & Complexity** +- **Input Size:** `n, m <= 500`. +- **Time Complexity:** O(m * k log k), where k is subarray length (sort each subarray). +- **Space Complexity:** O(k) per query for the sorted copy. +- **Edge Case:** Subarray of length 2 is always arithmetic. + +**1.2 High-level approach** +Extract subarray, sort it, ensure consecutive differences are equal. +![Sorted subarray check](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Try all permutations — factorial blowup. +- **Optimized:** Sorting then one pass diff check — O(k log k). + +**1.4 Decomposition** +1. For each query, copy subarray `nums[l:r+1]`. +2. Sort it. +3. Compute common diff = `sorted[1]-sorted[0]`. +4. Verify all consecutive diffs match; if any differ, mark false; else true. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `nums=[4,6,5,9,3,7]`, query `[0,2]` → subarray `[4,6,5]`. + +**2.2 Start Checking** +Sort → `[4,5,6]`, diff = 1. + +**2.3 Trace Walkthrough** +| Subarray (sorted) | Step | Diff check | OK? | +|-------------------|------|----------------------|-----| +| [4,5,6] | 4→5 | 1 == diff | ✓ | +| | 5→6 | 1 == diff | ✓ | + +**2.4 Increment and Loop** +Repeat for each query independently. + +**2.5 Return Result** +Append boolean for each query into `res`. + diff --git a/explanations/1823/en.md b/explanations/1823/en.md new file mode 100644 index 0000000..13cd293 --- /dev/null +++ b/explanations/1823/en.md @@ -0,0 +1,48 @@ +## Explanation + +### Strategy + +**Restate the problem** +`n` players in a circle, eliminate every `k`th; return the winner’s label (1-indexed). + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= k <= n <= 500`. +- **Time Complexity:** O(n) using the Josephus recurrence. +- **Space Complexity:** O(1). +- **Edge Case:** n=1 → winner=1. + +**1.2 High-level approach** +Use the Josephus recurrence: winner (0-indexed) updates as `winner = (winner + k) % i` for i from 2..n; convert to 1-indexed at the end. +![Josephus circular elimination](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Simulate with a queue/list and remove elements — O(n*k). +- **Optimized:** Closed-form recurrence — O(n). + +**1.4 Decomposition** +1. Set `winner = 0` (for i=1). +2. For `i` from 2 to `n`: `winner = (winner + k) % i`. +3. Return `winner + 1`. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `n=5, k=2`; start `winner=0`. + +**2.2 Start Checking** +Iterate i=2..5 updating winner. + +**2.3 Trace Walkthrough** +| i | winner before | update formula | winner after | +|---|---------------|----------------------|--------------| +| 2 | 0 | (0+2)%2 = 0 | 0 | +| 3 | 0 | (0+2)%3 = 2 | 2 | +| 4 | 2 | (2+2)%4 = 0 | 0 | +| 5 | 0 | (0+2)%5 = 2 | 2 | + +**2.4 Increment and Loop** +Loop until i = n. + +**2.5 Return Result** +Return `winner + 1` → 3 for the example. + diff --git a/explanations/2110/en.md b/explanations/2110/en.md new file mode 100644 index 0000000..f8a765f --- /dev/null +++ b/explanations/2110/en.md @@ -0,0 +1,50 @@ +## Explanation + +### Strategy + +**Restate the problem** +Count the number of contiguous subarrays where prices strictly descend by exactly 1 each day (a "smooth descent period"), including all single-day windows. + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= n <= 1e5`. +- **Time Complexity:** O(n) — single pass to accumulate lengths. +- **Space Complexity:** O(1) — constant counters only. +- **Edge Case:** A single element always forms a valid period. + +**1.2 High-level approach** +Traverse once, maintain the current descending run length; each position contributes that run length to the answer. +![Sliding window over descending runs](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Enumerate all subarrays and check descent — O(n²) checks. +- **Optimized:** Track run lengths in one pass — O(n). Avoids quadratic enumeration. + +**1.4 Decomposition** +1. Start run length at 1. +2. For each next price, if `prices[i] == prices[i-1]-1`, extend run; else reset to 1. +3. Add the current run length to `res`. +4. Return `res`. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `prices = [3,2,1,4]` +Set `run = 1`, `res = 1` (first day alone). + +**2.2 Start Checking** +Scan from index 1 to end, updating run and `res`. + +**2.3 Trace Walkthrough** +| i | prices[i] | Condition | run | res (cum) | +|---|-----------|--------------------------------|-----|-----------| +| 0 | 3 | start | 1 | 1 | +| 1 | 2 | 2 == 3-1 → extend | 2 | 3 | +| 2 | 1 | 1 == 2-1 → extend | 3 | 6 | +| 3 | 4 | 4 != 1-1 → reset | 1 | 7 | + +**2.4 Increment and Loop** +Each step updates `run` (either +1 or reset to 1) and adds it to `res`. + +**2.5 Return Result** +Final `res = 7` for the example. + diff --git a/explanations/2120/en.md b/explanations/2120/en.md new file mode 100644 index 0000000..c31c35d --- /dev/null +++ b/explanations/2120/en.md @@ -0,0 +1,51 @@ +## Explanation + +### Strategy + +**Restate the problem** +Given grid size `n`, start position, and instructions `s`, for each suffix of `s` compute how many moves stay within the grid. + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= n, m <= 500`, m = |s|. +- **Time Complexity:** O(m²) in the straightforward simulation (m up to 500 is fine). +- **Space Complexity:** O(1) extra besides output. +- **Edge Case:** Single instruction that immediately leaves → 0 for that suffix. + +**1.2 High-level approach** +For each starting index i, simulate moves from that suffix until leaving bounds. +![Suffix simulation on grid](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force / Direct:** Simulate each suffix independently — O(m²). Acceptable for m=500. +- **Optimized:** Could precompute deltas, but unnecessary here. + +**1.4 Decomposition** +1. Map instructions to direction deltas. +2. For each i in [0..m-1], start from `startPos`, step through `s[i:]` until out of bounds. +3. Count steps that remain in bounds. +4. Store counts in `res`. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `n=3, start=[0,1], s="RRDDLU"`, m=6. + +**2.2 Start Checking** +For each suffix, reset position and simulate. + +**2.3 Trace Walkthrough** +| start i | suffix | path validity count | +|---------|----------|---------------------| +| 0 | RRDDLU | 1 | +| 1 | RDDLU | 5 | +| 2 | DDLU | 4 | +| 3 | DLU | 3 | +| 4 | LU | 1 | +| 5 | U | 0 | + +**2.4 Increment and Loop** +Repeat for all suffix starts. + +**2.5 Return Result** +Return the array of counts, e.g., `[1,5,4,3,1,0]`. + diff --git a/explanations/2221/en.md b/explanations/2221/en.md new file mode 100644 index 0000000..0eacf26 --- /dev/null +++ b/explanations/2221/en.md @@ -0,0 +1,53 @@ +## Explanation + +### Strategy + +**Restate the problem** +Repeatedly replace the array with pairwise sums mod 10 until one element remains; return it. + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= n <= 1000`. +- **Time Complexity:** O(n²) in the direct simulation (each layer shrinks by 1). +- **Space Complexity:** O(n) for the working array. +- **Edge Case:** n=1 → return the single value. + +**1.2 High-level approach** +Simulate the reduction: build a new array of length-1 from `(nums[i]+nums[i+1]) % 10` until length=1. +![Layered triangular reduction](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Same as direct simulation — O(n²), acceptable for n=1000. +- **Optimized:** Binomial-coefficient mod 10 approach exists, but simulation suffices. + +**1.4 Decomposition** +1. While `len(nums) > 1`: + - Build `newNums` of size `len(nums)-1` with `(nums[i]+nums[i+1])%10`. + - Assign `nums = newNums`. +2. Return `nums[0]`. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `nums = [1,2,3,4,5]`. + +**2.2 Start Checking** +Layer 1: `[3,5,7,9]` → mod 10: `[3,5,7,9]` +Layer 2: `[8,2,6]` +Layer 3: `[0,8]` +Layer 4: `[8]` + +**2.3 Trace Walkthrough** +| Layer | Array state | +|-------|----------------| +| 0 | [1,2,3,4,5] | +| 1 | [3,5,7,9] | +| 2 | [8,2,6] | +| 3 | [0,8] | +| 4 | [8] | + +**2.4 Increment and Loop** +Repeat until a single value remains. + +**2.5 Return Result** +Return the last value (8 in the example). + diff --git a/explanations/2326/en.md b/explanations/2326/en.md new file mode 100644 index 0000000..0e42be8 --- /dev/null +++ b/explanations/2326/en.md @@ -0,0 +1,49 @@ +## Explanation + +### Strategy + +**Restate the problem** +Fill an `m x n` matrix in spiral order using values from a linked list; remaining cells become -1. + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= m*n <= 1e5`; list length up to `m*n`. +- **Time Complexity:** O(m*n) to visit each cell once. +- **Space Complexity:** O(1) extra (matrix output not counted). +- **Edge Case:** List shorter than cells → trailing -1s. + +**1.2 High-level approach** +Track boundaries/directions for spiral traversal, place list values until exhausted, then fill -1 stays. +![Spiral traversal boundaries](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Recompute visited checks with sets — higher overhead. +- **Optimized:** Direction vectors with boundary checks — O(1) per move. + +**1.4 Decomposition** +1. Initialize matrix with -1. +2. Set direction order: right, down, left, up. +3. Walk cell by cell, placing list values. +4. When the next cell is out-of-bounds or already filled, turn clockwise. +5. Continue until list ends or all cells visited. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `m=3, n=5`, list `[3,0,2,6,8,1,7,9,4,2,5,5,0]`; start at `(0,0)`, dir=right. + +**2.2 Start Checking** +Place value, attempt next move; if blocked, rotate direction. + +**2.3 Trace Walkthrough** +| Step | Pos (r,c) | Dir | Value placed | Next move valid? | +|------|-----------|--------|--------------|------------------| +| 1 | (0,0) | right | 3 | yes | +| ... | ... | ... | ... | ... | +| turn | boundary | rotate | — | — | + +**2.4 Increment and Loop** +Advance through list nodes; rotate as needed until list ends. + +**2.5 Return Result** +Matrix filled in spiral with remaining cells as -1. + diff --git a/explanations/237/en.md b/explanations/237/en.md index c20a9ea..c6426c7 100644 --- a/explanations/237/en.md +++ b/explanations/237/en.md @@ -2,6 +2,51 @@ ### Strategy +**Restate the problem** +Delete a given node (not tail) from a singly linked list when only that node reference is provided. + +**1.1 Constraints & Complexity** +- **Input Size:** 2 to 1000 nodes. +- **Time Complexity:** O(1) for the delete operation. +- **Space Complexity:** O(1). +- **Edge Case:** The given node’s next exists (guaranteed). + +**1.2 High-level approach** +Copy the next node’s value into the current node, then bypass the next node. +![In-place delete by copying next](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Traverse from head to find previous node — impossible without head. +- **Optimized:** Overwrite current node with next node data; O(1). + +**1.4 Decomposition** +1. Set `node.val = node.next.val`. +2. Link `node.next = node.next.next`. +3. Done. + +### Steps + +**2.1 Initialization & Example Setup** +List: `4 -> 5 -> 1 -> 9`, node to delete = value 5. + +**2.2 Start Checking** +Copy next (1) into current. + +**2.3 Trace Walkthrough** +| Step | node.val before | node.next.val | Action | List becomes | +|------|-----------------|---------------|-----------------------------|---------------------| +| 1 | 5 | 1 | node.val = 1 | 4 -> 1 -> 1 -> 9 | +| 2 | 1 | 1 | node.next = node.next.next | 4 -> 1 -> 9 | + +**2.4 Increment and Loop** +No loop; constant steps. + +**2.5 Return Result** +Node effectively removed; list is `4 -> 1 -> 9`. +## Explanation + +### Strategy + **Restate the problem** We need to delete a node from a linked list, but we are only given access to the node to be deleted (not the head). We cannot access the previous node directly. diff --git a/explanations/2482/en.md b/explanations/2482/en.md index 5273665..93db35d 100644 --- a/explanations/2482/en.md +++ b/explanations/2482/en.md @@ -2,6 +2,54 @@ ### Strategy +**Restate the problem** +For each cell `(i,j)` in a binary matrix, compute `onesRow[i] + onesCol[j] - zerosRow[i] - zerosCol[j]`. + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= m*n <= 1e5`. +- **Time Complexity:** O(m*n) to count and build output. +- **Space Complexity:** O(m + n) for row/col counts. +- **Edge Case:** Single cell matrix. + +**1.2 High-level approach** +Precompute ones per row and column, derive zeros from lengths, then fill the answer. +![Row/column accumulation](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** For each cell, scan its row and column — O(m*n*(m+n)). +- **Optimized:** Precompute counts once — O(m*n). + +**1.4 Decomposition** +1. Count `onesRow` for each row and `onesCol` for each column. +2. Derive `zerosRow[i] = n - onesRow[i]`, `zerosCol[j] = m - onesCol[j]`. +3. For each cell, compute the formula and store in `res`. +4. Return `res`. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `grid = [[0,1,1],[1,0,1],[0,0,1]]`. + +**2.2 Start Checking** +Compute `onesRow = [2,2,1]`, `onesCol = [1,1,3]`. + +**2.3 Trace Walkthrough** +| Cell (i,j) | onesRow[i] | onesCol[j] | zerosRow[i] | zerosCol[j] | diff | +|------------|------------|------------|-------------|-------------|------| +| (0,0) | 2 | 1 | 1 | 2 | 0 | +| (0,1) | 2 | 1 | 1 | 2 | 0 | +| (0,2) | 2 | 3 | 1 | 0 | 4 | +| ... | ... | ... | ... | ... | ... | + +**2.4 Increment and Loop** +Fill every cell using the precomputed counts. + +**2.5 Return Result** +Produces `[[0,0,4],[0,0,4],[-2,-2,2]]` for the example. +## Explanation + +### Strategy + **Restate the problem** We are given a binary matrix and need to create a difference matrix where each cell `diff[i][j]` is calculated as: ones in row i + ones in column j - zeros in row i - zeros in column j. diff --git a/explanations/2785/en.md b/explanations/2785/en.md new file mode 100644 index 0000000..cf087d9 --- /dev/null +++ b/explanations/2785/en.md @@ -0,0 +1,53 @@ +## Explanation + +### Strategy + +**Restate the problem** +Sort all vowels in the string by ASCII order while leaving consonants in place. + +**1.1 Constraints & Complexity** +- **Input Size:** `1 <= |s| <= 1e5`. +- **Time Complexity:** O(n log n) to sort extracted vowels; O(n) if counting-sort on 10 vowel chars. +- **Space Complexity:** O(n) for the output list. +- **Edge Case:** No vowels → string unchanged. + +**1.2 High-level approach** +Extract vowels, sort them, then rebuild the string by replacing vowel positions with sorted vowels. +![Extract-sort-rebuild pipeline](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** Repeatedly scan to find next smallest vowel — O(n²). +- **Optimized:** One pass extract + one sort + one rebuild — O(n log n). + +**1.4 Decomposition** +1. Collect vowels into a list. +2. Sort the vowel list. +3. Rebuild string: if char is vowel, take next from sorted list; else keep consonant. +4. Join result. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `s = "lEetcOde"`; vowels extracted: `['E','e','O','e']`. + +**2.2 Start Checking** +Sort vowels → `['E','O','e','e']`. + +**2.3 Trace Walkthrough** +| Index | Char | Is vowel? | Replacement | Result so far | +|-------|------|-----------|--------------------|---------------| +| 0 | l | No | l | l | +| 1 | E | Yes | E (sorted[0]) | lE | +| 2 | e | Yes | O (sorted[1]) | lEO | +| 3 | t | No | t | lEOt | +| 4 | c | No | c | lEOtc | +| 5 | O | Yes | e (sorted[2]) | lEOtce | +| 6 | d | No | d | lEOtced | +| 7 | e | Yes | e (sorted[3]) | lEOtcede | + +**2.4 Increment and Loop** +Advance through string, consuming sorted vowels sequentially. + +**2.5 Return Result** +Final string: `"lEOtcede"`. + diff --git a/explanations/797/en.md b/explanations/797/en.md index 2f3db91..d003ff6 100644 --- a/explanations/797/en.md +++ b/explanations/797/en.md @@ -2,6 +2,54 @@ ### Strategy +**Restate the problem** +Given a DAG adjacency list, enumerate all paths from node 0 to node n-1. + +**1.1 Constraints & Complexity** +- **Input Size:** `2 <= n <= 15`. +- **Time Complexity:** O(P * L), where P is number of paths and L their length (DFS visits each edge per path). +- **Space Complexity:** O(L) recursion stack + output. +- **Edge Case:** Single edge 0→1. + +**1.2 High-level approach** +DFS from 0, accumulate nodes in a path; when reaching n-1, record the path. +![DFS path enumeration](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png) + +**1.3 Brute force vs. optimized strategy** +- **Brute Force:** None better is needed; DFS naturally enumerates all paths. +- **Optimized:** Use backtracking to avoid extra copies while exploring. + +**1.4 Decomposition** +1. Start DFS at node 0 with path `[0]`. +2. For each neighbor, append, recurse, then pop. +3. If node == n-1, push a copy of path to results. +4. Return all collected paths. + +### Steps + +**2.1 Initialization & Example Setup** +Example: `graph = [[1,2],[3],[3],[]]`, n=4. + +**2.2 Start Checking** +Begin at 0; explore neighbors 1 and 2. + +**2.3 Trace Walkthrough** +| Path stack | Next step | Action | +|------------|------------------|------------------| +| [0] | neighbor 1 | recurse | +| [0,1] | neighbor 3 | reach n-1 → save | +| [0] | neighbor 2 | recurse | +| [0,2] | neighbor 3 | reach n-1 → save | + +**2.4 Increment and Loop** +Backtrack after each neighbor; continue until all explored. + +**2.5 Return Result** +`[[0,1,3],[0,2,3]]` for the example. +## Explanation + +### Strategy + **Restate the problem** We need to find all paths from node 0 to node n-1 in a directed acyclic graph (DAG). Each path is a sequence of nodes connected by edges. diff --git a/solutions/1008/01.py b/solutions/1008/01.py index 708fa36..135eddd 100644 --- a/solutions/1008/01.py +++ b/solutions/1008/01.py @@ -4,18 +4,20 @@ # self.val = val # self.left = left # self.right = right +from typing import List, Optional + class Solution: def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]: if not preorder: return None - + root = TreeNode(preorder[0]) stack = [root] - + for val in preorder[1:]: node = TreeNode(val) - - # If current value is less than stack top, it's left child + + # If current value is less than stack top, it's a left child if val < stack[-1].val: stack[-1].left = node else: @@ -23,7 +25,7 @@ def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]: while stack and stack[-1].val < val: parent = stack.pop() parent.right = node - + stack.append(node) - + return root diff --git a/solutions/1079/01.py b/solutions/1079/01.py index 88c89e1..d529fa9 100644 --- a/solutions/1079/01.py +++ b/solutions/1079/01.py @@ -1,16 +1,20 @@ +from collections import Counter + class Solution: def numTilePossibilities(self, tiles: str) -> int: - from collections import Counter - - def backtrack(count): - res = 0 + count = Counter(tiles) + res = 0 + + def backtrack(): + nonlocal res for char in count: if count[char] > 0: - res += 1 # Count this sequence + # Use this character count[char] -= 1 - res += backtrack(count) # Continue building - count[char] += 1 # Backtrack - return res - - count = Counter(tiles) - return backtrack(count) + res += 1 + backtrack() + # Backtrack + count[char] += 1 + + backtrack() + return res diff --git a/solutions/1261/01.py b/solutions/1261/01.py index 19ad1df..307b0df 100644 --- a/solutions/1261/01.py +++ b/solutions/1261/01.py @@ -4,25 +4,20 @@ # self.val = val # self.left = left # self.right = right -class FindElements: +from typing import Optional +class FindElements: def __init__(self, root: Optional[TreeNode]): self.values = set() - + def recover(node, val): - if not node: - return - node.val = val - self.values.add(val) - recover(node.left, 2 * val + 1) - recover(node.right, 2 * val + 2) - + if node: + node.val = val + self.values.add(val) + recover(node.left, 2 * val + 1) + recover(node.right, 2 * val + 2) + recover(root, 0) def find(self, target: int) -> bool: return target in self.values - - -# Your FindElements object will be instantiated and called as such: -# obj = FindElements(root) -# param_1 = obj.find(target) diff --git a/solutions/1347/01.py b/solutions/1347/01.py index bcb0551..06fd461 100644 --- a/solutions/1347/01.py +++ b/solutions/1347/01.py @@ -1,13 +1,14 @@ +from collections import Counter + class Solution: def minSteps(self, s: str, t: str) -> int: - from collections import Counter - count_s = Counter(s) count_t = Counter(t) - + res = 0 + # Count characters that need to be changed in t for char in count_s: - if count_s[char] > count_t[char]: + if count_t[char] < count_s[char]: res += count_s[char] - count_t[char] - + return res diff --git a/solutions/1551/01.py b/solutions/1551/01.py index da1f22f..c3f0a2a 100644 --- a/solutions/1551/01.py +++ b/solutions/1551/01.py @@ -1,17 +1,15 @@ class Solution: - def findMinFibonacciNumbers(self, k: int) -> int: - # Generate Fibonacci numbers up to k - fib = [1, 1] - while fib[-1] < k: - fib.append(fib[-1] + fib[-2]) - - # Greedy: use largest Fibonacci number <= remaining k + def minOperations(self, n: int) -> int: + # The array is [1, 3, 5, ..., 2*n-1] + # Target value is the average: (1 + 2*n-1) / 2 = n + # For each element at index i, value is 2*i + 1 + # Operations needed to make it equal to n: |(2*i + 1) - n| + # But we only need to count half since we can pair operations + res = 0 - idx = len(fib) - 1 - while k > 0: - while fib[idx] > k: - idx -= 1 - k -= fib[idx] - res += 1 - + for i in range(n // 2): + target = n + current = 2 * i + 1 + res += target - current + return res diff --git a/solutions/1605/01.py b/solutions/1605/01.py index 4e4ee73..95e200c 100644 --- a/solutions/1605/01.py +++ b/solutions/1605/01.py @@ -1,14 +1,16 @@ +from typing import List + class Solution: def restoreMatrix(self, rowSum: List[int], colSum: List[int]) -> List[List[int]]: m, n = len(rowSum), len(colSum) res = [[0] * n for _ in range(m)] - + for i in range(m): for j in range(n): - # Place minimum of remaining row sum and column sum + # Place the minimum of remaining rowSum and colSum val = min(rowSum[i], colSum[j]) res[i][j] = val rowSum[i] -= val colSum[j] -= val - + return res diff --git a/solutions/1630/01.py b/solutions/1630/01.py index 0aad93a..21e3546 100644 --- a/solutions/1630/01.py +++ b/solutions/1630/01.py @@ -1,25 +1,26 @@ +from typing import List + class Solution: - def checkArithmeticSubarrays( - self, nums: List[int], l: List[int], r: List[int] - ) -> List[bool]: + def checkArithmeticSubarrays(self, nums: List[int], l: List[int], r: List[int]) -> List[bool]: res = [] - + for i in range(len(l)): - subarray = nums[l[i] : r[i] + 1] - subarray.sort() - - if len(subarray) < 2: + # Extract subarray + subarray = nums[l[i]:r[i] + 1] + + # Sort the subarray + sorted_sub = sorted(subarray) + + # Check if it's arithmetic + if len(sorted_sub) <= 1: res.append(True) - continue - - diff = subarray[1] - subarray[0] - is_arithmetic = True - - for j in range(1, len(subarray)): - if subarray[j] - subarray[j - 1] != diff: - is_arithmetic = False - break - - res.append(is_arithmetic) - + else: + diff = sorted_sub[1] - sorted_sub[0] + is_arithmetic = True + for j in range(2, len(sorted_sub)): + if sorted_sub[j] - sorted_sub[j - 1] != diff: + is_arithmetic = False + break + res.append(is_arithmetic) + return res diff --git a/solutions/1823/01.py b/solutions/1823/01.py index 02eacdc..42eb7e9 100644 --- a/solutions/1823/01.py +++ b/solutions/1823/01.py @@ -1,8 +1,9 @@ class Solution: def findTheWinner(self, n: int, k: int) -> int: - # Josephus problem - # Use 0-indexed, then convert to 1-indexed at the end - res = 0 + # Use Josephus problem solution + # For 0-indexed: winner = (winner + k) % n + # Convert to 1-indexed at the end + winner = 0 for i in range(2, n + 1): - res = (res + k) % i - return res + 1 + winner = (winner + k) % i + return winner + 1 diff --git a/solutions/2110/01.py b/solutions/2110/01.py new file mode 100644 index 0000000..57f6cde --- /dev/null +++ b/solutions/2110/01.py @@ -0,0 +1,22 @@ +from typing import List + +class Solution: + def getDescentPeriods(self, prices: List[int]) -> int: + n = len(prices) + res = 0 + i = 0 + + while i < n: + # Find the length of the current smooth descent period + length = 1 + while i + length < n and prices[i + length] == prices[i + length - 1] - 1: + length += 1 + + # Count all subarrays within this period + # For a period of length k, there are k*(k+1)//2 subarrays + res += length * (length + 1) // 2 + + i += length + + return res + diff --git a/solutions/2120/01.py b/solutions/2120/01.py index 8997322..1204b10 100644 --- a/solutions/2120/01.py +++ b/solutions/2120/01.py @@ -1,9 +1,33 @@ -class Solution: - def sumOfThree(self, num: int) -> List[int]: - # If num = (x-1) + x + (x+1) = 3x - # Then x = num / 3 - if num % 3 != 0: - return [] +from typing import List - x = num // 3 - return [x - 1, x, x + 1] +class Solution: + def executeInstructions(self, n: int, startPos: List[int], s: str) -> List[int]: + m = len(s) + res = [] + + # Direction mapping + directions = { + 'L': (0, -1), + 'R': (0, 1), + 'U': (-1, 0), + 'D': (1, 0) + } + + for i in range(m): + row, col = startPos[0], startPos[1] + count = 0 + + for j in range(i, m): + dr, dc = directions[s[j]] + new_row, new_col = row + dr, col + dc + + # Check if next move is valid + if 0 <= new_row < n and 0 <= new_col < n: + row, col = new_row, new_col + count += 1 + else: + break + + res.append(count) + + return res diff --git a/solutions/2221/01.py b/solutions/2221/01.py index fbcd23d..80b7ec2 100644 --- a/solutions/2221/01.py +++ b/solutions/2221/01.py @@ -1,15 +1,10 @@ -class Solution: - def findChampion(self, grid: List[List[int]]) -> int: - n = len(grid) - - # Find team that beats all others (row has all 1s except diagonal) - for i in range(n): - is_champion = True - for j in range(n): - if i != j and grid[i][j] == 0: - is_champion = False - break - if is_champion: - return i +from typing import List - return -1 +class Solution: + def triangularSum(self, nums: List[int]) -> int: + while len(nums) > 1: + new_nums = [] + for i in range(len(nums) - 1): + new_nums.append((nums[i] + nums[i + 1]) % 10) + nums = new_nums + return nums[0] diff --git a/solutions/2326/01.py b/solutions/2326/01.py index b1dd03d..eb9c40a 100644 --- a/solutions/2326/01.py +++ b/solutions/2326/01.py @@ -3,38 +3,37 @@ # def __init__(self, val=0, next=None): # self.val = val # self.next = next +from typing import List, Optional + class Solution: def spiralMatrix(self, m: int, n: int, head: Optional[ListNode]) -> List[List[int]]: # Initialize matrix with -1 res = [[-1] * n for _ in range(m)] - + # Directions: right, down, left, up directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] dir_idx = 0 row, col = 0, 0 - + current = head while current: res[row][col] = current.val current = current.next - - # Calculate next position - dr, dc = directions[dir_idx] - next_row, next_col = row + dr, col + dc - + + if not current: + break + + # Try to move in current direction + next_row = row + directions[dir_idx][0] + next_col = col + directions[dir_idx][1] + # Check if we need to change direction - if ( - next_row < 0 - or next_row >= m - or next_col < 0 - or next_col >= n - or res[next_row][next_col] != -1 - ): - # Change direction + if (next_row < 0 or next_row >= m or + next_col < 0 or next_col >= n or + res[next_row][next_col] != -1): dir_idx = (dir_idx + 1) % 4 - dr, dc = directions[dir_idx] - next_row, next_col = row + dr, col + dc - - row, col = next_row, next_col - + + row += directions[dir_idx][0] + col += directions[dir_idx][1] + return res diff --git a/solutions/237/01.py b/solutions/237/01.py index b17ab48..3a2a0c2 100644 --- a/solutions/237/01.py +++ b/solutions/237/01.py @@ -4,14 +4,13 @@ # self.val = x # self.next = None - class Solution: def deleteNode(self, node): """ :type node: ListNode :rtype: void Do not return anything, modify node in-place instead. """ - # Copy next node's value to current node + # Copy value from next node node.val = node.next.val - # Skip the next node + # Skip next node node.next = node.next.next diff --git a/solutions/2482/01.py b/solutions/2482/01.py index 24927b9..f1fc9cc 100644 --- a/solutions/2482/01.py +++ b/solutions/2482/01.py @@ -1,23 +1,28 @@ +from typing import List + class Solution: def onesMinusZeros(self, grid: List[List[int]]) -> List[List[int]]: m, n = len(grid), len(grid[0]) - + # Count ones in each row and column - ones_row = [0] * m - ones_col = [0] * n - + onesRow = [0] * m + onesCol = [0] * n + for i in range(m): for j in range(n): if grid[i][j] == 1: - ones_row[i] += 1 - ones_col[j] += 1 - + onesRow[i] += 1 + onesCol[j] += 1 + # Build result matrix - res = [[0] * n for _ in range(m)] + res = [] for i in range(m): + row = [] for j in range(n): - zeros_row = n - ones_row[i] - zeros_col = m - ones_col[j] - res[i][j] = ones_row[i] + ones_col[j] - zeros_row - zeros_col - + zerosRow = n - onesRow[i] + zerosCol = m - onesCol[j] + diff = onesRow[i] + onesCol[j] - zerosRow - zerosCol + row.append(diff) + res.append(row) + return res diff --git a/solutions/2637/01.py b/solutions/2637/01.py index a24f828..6527b7f 100644 --- a/solutions/2637/01.py +++ b/solutions/2637/01.py @@ -1,12 +1,14 @@ +from typing import List + class Solution: def rowAndMaximumOnes(self, mat: List[List[int]]) -> List[int]: max_ones = -1 - max_row = 0 - + max_row = -1 + for i, row in enumerate(mat): - ones_count = sum(row) - if ones_count > max_ones: - max_ones = ones_count + ones = sum(row) + if ones > max_ones: + max_ones = ones max_row = i - + return [max_row, max_ones] diff --git a/solutions/2785/01.py b/solutions/2785/01.py index c08db60..c0aac64 100644 --- a/solutions/2785/01.py +++ b/solutions/2785/01.py @@ -1,19 +1,19 @@ class Solution: def sortVowels(self, s: str) -> str: - vowels = {"a", "e", "i", "o", "u", "A", "E", "I", "O", "U"} - - # Extract and sort vowels - vowel_list = [char for char in s if char in vowels] + vowels = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'} + + # Extract vowels and sort them + vowel_list = [c for c in s if c in vowels] vowel_list.sort() - + # Build result res = [] vowel_idx = 0 - for char in s: - if char in vowels: + for c in s: + if c in vowels: res.append(vowel_list[vowel_idx]) vowel_idx += 1 else: - res.append(char) - - return "".join(res) + res.append(c) + + return ''.join(res) diff --git a/solutions/3271/01.py b/solutions/3271/01.py new file mode 100644 index 0000000..f445439 --- /dev/null +++ b/solutions/3271/01.py @@ -0,0 +1,10 @@ +class Solution: + def stringHash(self, s: str, k: int) -> str: + # Process the string in chunks of length k and compute hashed chars. + res = [] + for i in range(0, len(s), k): + chunk = s[i : i + k] + total = sum(ord(c) - ord('a') for c in chunk) + hashed = total % 26 + res.append(chr(ord('a') + hashed)) + return ''.join(res) diff --git a/solutions/797/01.py b/solutions/797/01.py index 68433e3..28a1a81 100644 --- a/solutions/797/01.py +++ b/solutions/797/01.py @@ -1,17 +1,19 @@ +from typing import List + class Solution: def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]: res = [] n = len(graph) - + def dfs(node, path): if node == n - 1: res.append(path[:]) return - + for neighbor in graph[node]: path.append(neighbor) dfs(neighbor, path) path.pop() - + dfs(0, [0]) return res