diff --git a/books/All.md b/books/All.md index 6104f46..f59526f 100644 --- a/books/All.md +++ b/books/All.md @@ -8922,68 +8922,6 @@ class Solution: return res ``` -## 1431. Kids With the Greatest Number of Candies [Easy] -https://leetcode.com/problems/kids-with-the-greatest-number-of-candies/ - -### Explanation - -## 1431. Kids With the Greatest Number of Candies [Easy] - -https://leetcode.com/problems/kids-with-the-greatest-number-of-candies - -## Description -There are `n` kids with candies. You are given an integer array `candies`, where each `candies[i]` represents the number of candies the `i`th kid has, and an integer `extraCandies`, denoting the number of extra candies that you have. - -Return a boolean array `result` of length `n`, where `result[i]` is `true` if, after giving the `i`th kid all the `extraCandies`, they will have the greatest number of candies among all the kids, or false otherwise. - -Note that multiple kids can have the greatest number of candies. - -**Examples** - -```text -Input: candies = [2,3,5,1,3], extraCandies = 3 -Output: [true,true,true,false,true] -Explanation: If you give all extraCandies to: -- Kid 1, they will have 2 + 3 = 5 candies, which is the greatest among the kids. -- Kid 2, they will have 3 + 3 = 6 candies, which is the greatest among the kids. -- Kid 3, they will have 5 + 3 = 8 candies, which is the greatest among the kids. -- Kid 4, they will have 1 + 3 = 4 candies, which is not the greatest among the kids. -- Kid 5, they will have 3 + 3 = 6 candies, which is the greatest among the kids. - -Input: candies = [4,2,1,1,2], extraCandies = 1 -Output: [true,false,false,false,false] - -Input: candies = [12,1,12], extraCandies = 10 -Output: [true,false,true] -``` - -**Constraints** - -```text -- n == candies.length -- 2 <= n <= 100 -- 1 <= candies[i] <= 100 -- 1 <= extraCandies <= 50 -``` - -## Hint -For each kid, check if their candies plus `extraCandies` is at least as much as the current maximum. - -## Explanation -First, you want to know the highest number of candies any kid currently has. This is important because you need a reference point to see if giving extra candies to a kid will make them "the greatest." - -For each kid, you add the `extraCandies` to their current amount. You do this because you want to see if, after the bonus, they can reach or beat the current maximum. If they do, you mark them as `True` in our answer list; otherwise, False. - -You only need to find the maximum once, and then just compare each kid's total to it. Don't need to recalculate the maximum for every kid. - -### Solution - -```python -def kidsWithCandies(candies, extraCandies): - max_candies = max(candies) # Find the current maximum - return [(c + extraCandies) >= max_candies for c in candies] -``` - ## 1448. Count Good Nodes in Binary Tree [Medium] https://leetcode.com/problems/count-good-nodes-in-binary-tree/ diff --git a/books/LeetCode_75.md b/books/LeetCode_75.md index 855013e..1644d29 100644 --- a/books/LeetCode_75.md +++ b/books/LeetCode_75.md @@ -517,68 +517,6 @@ def uniqueOccurrences(arr): return len(set(count.values())) == len(count) ``` -## 1431. Kids With the Greatest Number of Candies [Easy] -https://leetcode.com/problems/kids-with-the-greatest-number-of-candies/ - -### Explanation - -## 1431. Kids With the Greatest Number of Candies [Easy] - -https://leetcode.com/problems/kids-with-the-greatest-number-of-candies - -## Description -There are `n` kids with candies. You are given an integer array `candies`, where each `candies[i]` represents the number of candies the `i`th kid has, and an integer `extraCandies`, denoting the number of extra candies that you have. - -Return a boolean array `result` of length `n`, where `result[i]` is `true` if, after giving the `i`th kid all the `extraCandies`, they will have the greatest number of candies among all the kids, or false otherwise. - -Note that multiple kids can have the greatest number of candies. - -**Examples** - -```text -Input: candies = [2,3,5,1,3], extraCandies = 3 -Output: [true,true,true,false,true] -Explanation: If you give all extraCandies to: -- Kid 1, they will have 2 + 3 = 5 candies, which is the greatest among the kids. -- Kid 2, they will have 3 + 3 = 6 candies, which is the greatest among the kids. -- Kid 3, they will have 5 + 3 = 8 candies, which is the greatest among the kids. -- Kid 4, they will have 1 + 3 = 4 candies, which is not the greatest among the kids. -- Kid 5, they will have 3 + 3 = 6 candies, which is the greatest among the kids. - -Input: candies = [4,2,1,1,2], extraCandies = 1 -Output: [true,false,false,false,false] - -Input: candies = [12,1,12], extraCandies = 10 -Output: [true,false,true] -``` - -**Constraints** - -```text -- n == candies.length -- 2 <= n <= 100 -- 1 <= candies[i] <= 100 -- 1 <= extraCandies <= 50 -``` - -## Hint -For each kid, check if their candies plus `extraCandies` is at least as much as the current maximum. - -## Explanation -First, you want to know the highest number of candies any kid currently has. This is important because you need a reference point to see if giving extra candies to a kid will make them "the greatest." - -For each kid, you add the `extraCandies` to their current amount. You do this because you want to see if, after the bonus, they can reach or beat the current maximum. If they do, you mark them as `True` in our answer list; otherwise, False. - -You only need to find the maximum once, and then just compare each kid's total to it. Don't need to recalculate the maximum for every kid. - -### Solution - -```python -def kidsWithCandies(candies, extraCandies): - max_candies = max(candies) # Find the current maximum - return [(c + extraCandies) >= max_candies for c in candies] -``` - ## 2215. Find the Difference of Two Arrays [Easy] https://leetcode.com/problems/find-the-difference-of-two-arrays/ diff --git a/books/Visualization.md b/books/Visualization.md index f58ae53..d8300b2 100644 --- a/books/Visualization.md +++ b/books/Visualization.md @@ -86,68 +86,6 @@ def __init__(self, val=0, next=None): self.next = next ``` -## 1431. Kids With the Greatest Number of Candies [Easy] -https://leetcode.com/problems/kids-with-the-greatest-number-of-candies/ - -### Explanation - -## 1431. Kids With the Greatest Number of Candies [Easy] - -https://leetcode.com/problems/kids-with-the-greatest-number-of-candies - -## Description -There are `n` kids with candies. You are given an integer array `candies`, where each `candies[i]` represents the number of candies the `i`th kid has, and an integer `extraCandies`, denoting the number of extra candies that you have. - -Return a boolean array `result` of length `n`, where `result[i]` is `true` if, after giving the `i`th kid all the `extraCandies`, they will have the greatest number of candies among all the kids, or false otherwise. - -Note that multiple kids can have the greatest number of candies. - -**Examples** - -```text -Input: candies = [2,3,5,1,3], extraCandies = 3 -Output: [true,true,true,false,true] -Explanation: If you give all extraCandies to: -- Kid 1, they will have 2 + 3 = 5 candies, which is the greatest among the kids. -- Kid 2, they will have 3 + 3 = 6 candies, which is the greatest among the kids. -- Kid 3, they will have 5 + 3 = 8 candies, which is the greatest among the kids. -- Kid 4, they will have 1 + 3 = 4 candies, which is not the greatest among the kids. -- Kid 5, they will have 3 + 3 = 6 candies, which is the greatest among the kids. - -Input: candies = [4,2,1,1,2], extraCandies = 1 -Output: [true,false,false,false,false] - -Input: candies = [12,1,12], extraCandies = 10 -Output: [true,false,true] -``` - -**Constraints** - -```text -- n == candies.length -- 2 <= n <= 100 -- 1 <= candies[i] <= 100 -- 1 <= extraCandies <= 50 -``` - -## Hint -For each kid, check if their candies plus `extraCandies` is at least as much as the current maximum. - -## Explanation -First, you want to know the highest number of candies any kid currently has. This is important because you need a reference point to see if giving extra candies to a kid will make them "the greatest." - -For each kid, you add the `extraCandies` to their current amount. You do this because you want to see if, after the bonus, they can reach or beat the current maximum. If they do, you mark them as `True` in our answer list; otherwise, False. - -You only need to find the maximum once, and then just compare each kid's total to it. Don't need to recalculate the maximum for every kid. - -### Solution - -```python -def kidsWithCandies(candies, extraCandies): - max_candies = max(candies) # Find the current maximum - return [(c + extraCandies) >= max_candies for c in candies] -``` - ## 1798. Maximum Number of Consecutive Values You Can Make [Medium] https://leetcode.com/problems/maximum-number-of-consecutive-values-you-can-make/ diff --git a/data/book-sets.json b/data/book-sets.json index 8354710..13e5a4b 100644 --- a/data/book-sets.json +++ b/data/book-sets.json @@ -61,9 +61,9 @@ 1304, 1318, 1337, 1372, 1423, 1431, 1448, 1456, 1466, 1480, 1493, 1515, 1523, 1528, 1557, 1584, 1657, 1672, 1679, 1704, 1732, 1768, 1798, 1920, 1925, 1926, 1929, 1957, 1963, 2011, 2095, 2119, 2130, 2211, 2215, 2300, 2336, 2352, 2390, 2419, 2462, 2542, 2627, 2703, 2723, 2769, 2807, 2862, 2879, 2884, 2888, 2894, 2942, 3100, 3110, 3133, 3164, 3190, 3197, 3228, 3291, 3320, 3351, 3380, 3381, 3413, 3424, 3432, 3444, 3471, 3512, 3522, - 3602, 3603, 3606, 3607, 3608, 3622, 3623, 3625, 3663, 3668, 3678, 3683, 3688, 3692, 3697, 3701, 3707, 3712, 3718, 3722, 3723, 3724, 3726, 3727, - 3728, 3731, 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3745, 3747, 3748, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3759, 3760, 3761, - 3762, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772 + 3583, 3602, 3603, 3606, 3607, 3608, 3622, 3623, 3625, 3663, 3668, 3678, 3683, 3688, 3692, 3697, 3701, 3707, 3712, 3718, 3722, 3723, 3724, 3726, + 3727, 3728, 3731, 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3745, 3747, 3748, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3759, 3760, + 3761, 3764, 3765, 3766, 3767, 3768, 3770, 3771, 3772 ] }, {"title": "Visualization", "description": "", "tags": [], "problems": [1, 2, 11, 1431, 1679, 1768, 1798, 2215, 3603, 3622, 3623]}, diff --git a/explanations/3722/en.md b/explanations/3722/en.md index 3cc5d01..fa96b47 100644 --- a/explanations/3722/en.md +++ b/explanations/3722/en.md @@ -1,73 +1,67 @@ ## Explanation -### Strategy (The "Why") +### Strategy -**1.1 Constraints & Complexity:** +**1.1 Constraints & Complexity** -- **Constraints:** $1 \leq n \leq 1000$ where $n$ is the string length. String contains only lowercase English letters. -- **Time Complexity:** $O(n^2)$ where $n$ is the string length. We try $2n$ operations, each involving string reversal which is $O(n)$. -- **Space Complexity:** $O(n)$ for storing reversed strings. -- **Edge Case:** If the string is already lexicographically smallest, return it unchanged. + * **Input Size:** The string `s` has length `n` where `1 <= n <= 1000`. This is a small constraint that allows for a straightforward approach. + * **Time Complexity:** O(n^2) - We try all possible values of `k` from 1 to `n` for both prefix and suffix reversals, and each reversal operation takes O(n) time. + * **Space Complexity:** O(n) - We create new string candidates for comparison, but we only keep the best one at any time. + * **Edge Case:** If no reversal produces a lexicographically smaller string, we return the original string. -**1.2 High-level approach:** +**1.2 High-level approach** -The goal is to find the lexicographically smallest string after performing exactly one operation: either reversing the first $k$ characters or the last $k$ characters for some $k$. We try all possible operations and return the lexicographically smallest result. +The goal is to find the lexicographically smallest string achievable by performing exactly one reversal operation (either on the first `k` characters or the last `k` characters). -**1.3 Brute force vs. optimized strategy:** +Imagine you have a string written on cards. You can flip either the leftmost `k` cards or the rightmost `k` cards exactly once, and you want the resulting arrangement to be as small as possible when read left to right. -- **Brute Force:** Try all $2n$ possible operations (reverse first $k$ for $k=1$ to $n$, reverse last $k$ for $k=1$ to $n$), compare results. This is $O(n^2)$ time. -- **Optimized Strategy:** Same as brute force - we need to check all possibilities since there's no obvious pattern to skip. This is $O(n^2)$ time. -- **Why this approach:** The problem constraints allow $O(n^2)$ solution, and there's no obvious optimization to avoid checking all operations. +**1.3 Brute force vs. optimized strategy** -**1.4 Decomposition:** + * **Brute Force:** Try all possible values of `k` from 1 to `n` for prefix reversals, and all possible values of `k` from 1 to `n` for suffix reversals. For each candidate, compare it lexicographically with the current best result. This is exactly what we do, and it's efficient enough given the small constraint. + * **Optimized Strategy:** The brute force approach is already optimal for this problem size. We systematically check all `2n` possible operations (n prefix reversals + n suffix reversals) and keep track of the lexicographically smallest result. -1. Initialize result as the original string. -2. Try reversing first $k$ characters for $k = 1$ to $n$: - - Reverse `s[:k]` and concatenate with `s[k:]` - - Update result if this is lexicographically smaller. -3. Try reversing last $k$ characters for $k = 1$ to $n$: - - Keep `s[:n-k]` and reverse `s[n-k:]` - - Update result if this is lexicographically smaller. -4. Return the result. +**1.4 Decomposition** -### Steps (The "How") +1. Initialize the result with the original string as the baseline. +2. Try all prefix reversals: For each `k` from 1 to `n`, reverse the first `k` characters and compare the result. +3. Try all suffix reversals: For each `k` from 1 to `n`, reverse the last `k` characters and compare the result. +4. Update the result whenever we find a lexicographically smaller candidate. +5. Return the smallest string found. -**2.1 Initialization & Example Setup:** +### Steps -Let's use the example: `s = "dcab"` +**2.1 Initialization & Example Setup** -We initialize `res = "dcab"`. +Let's use the example `s = "dcab"` to trace through the solution. -**2.2 Start Checking:** +We initialize `res = "dcab"` as our current best result. -We try all possible reversal operations. +**2.2 Start Checking/Processing** -**2.3 Trace Walkthrough:** +We begin by trying all possible prefix reversals (reversing the first `k` characters) for `k` from 1 to `n`. -**Reverse first k characters:** -- k=1: "d" + "cab" = "dcab" (not smaller) -- k=2: "cd" + "ab" = "cdab" (not smaller) -- k=3: "acd" + "b" = "acdb" (smaller! update res) -- k=4: "bacd" (not smaller) +**2.3 Trace Walkthrough** -**Reverse last k characters:** -- k=1: "dca" + "b" = "dcab" (not smaller) -- k=2: "dc" + "ba" = "dcba" (not smaller) -- k=3: "d" + "bac" = "dbac" (not smaller) -- k=4: "bacd" (not smaller) +| k | Prefix to Reverse | Reversed Prefix | Remaining | Candidate | Is Smaller? | Update res? | +|---|-------------------|-----------------|-----------|-----------|-------------|--------------| +| 1 | "d" | "d" | "cab" | "dcab" | No | No | +| 2 | "dc" | "cd" | "ab" | "cdab" | No | No | +| 3 | "dca" | "acd" | "b" | "acdb" | Yes | Yes → "acdb" | +| 4 | "dcab" | "bacd" | "" | "bacd" | No | No | -Best result: "acdb" +Now we try suffix reversals (reversing the last `k` characters): -**2.4 Increment and Loop:** +| k | Suffix to Reverse | Remaining | Reversed Suffix | Candidate | Is Smaller? | Update res? | +|---|-------------------|-----------|-----------------|-----------|-------------|--------------| +| 1 | "b" | "dca" | "b" | "dcab" | No | No | +| 2 | "ab" | "dc" | "ba" | "dcba" | No | No | +| 3 | "cab" | "d" | "bac" | "dbac" | No | No | +| 4 | "dcab" | "" | "bacd" | "bacd" | No | No | -- For $k$ from 1 to $n$: - - `reversed_str = s[:k][::-1] + s[k:]` - - `if reversed_str < res: res = reversed_str` -- For $k$ from 1 to $n$: - - `reversed_str = s[:n-k] + s[n-k:][::-1]` - - `if reversed_str < res: res = reversed_str` +**2.4 Increment and Loop** -**2.5 Return Result:** +After checking all prefix reversals, we move to checking all suffix reversals. We continue until we've examined all `2n` possible operations. -For `s = "dcab"`, the lexicographically smallest result is "acdb" (obtained by reversing the first 3 characters). We return "acdb". +**2.5 Return Result** +The lexicographically smallest string found is `"acdb"`, which we return as the final result. diff --git a/explanations/3727/en.md b/explanations/3727/en.md index 1fc768a..928811d 100644 --- a/explanations/3727/en.md +++ b/explanations/3727/en.md @@ -1,65 +1,61 @@ ## Explanation -### Strategy (The "Why") +### Strategy -**1.1 Constraints & Complexity:** +**1.1 Constraints & Complexity** -- **Constraints:** $1 \leq n \leq 10^5$ elements. Values are in the range $[-4 \times 10^4, 4 \times 10^4]$. -- **Time Complexity:** $O(n \log n)$ for sorting the array. -- **Space Complexity:** $O(n)$ for the sorted array. -- **Edge Case:** If the array has one element, return its square. + * **Input Size:** The array `nums` has length `n` where `1 <= n <= 10^5`. Values range from `-4 * 10^4` to `4 * 10^4`. + * **Time Complexity:** O(n log n) - We sort the array of squares, which dominates the time complexity. + * **Space Complexity:** O(n) - We create an array of squares and sort it. + * **Edge Case:** For a single element, the alternating sum is just that element squared. -**1.2 High-level approach:** +**1.2 High-level approach** -The goal is to maximize the alternating sum of squares: $arr[0]^2 - arr[1]^2 + arr[2]^2 - arr[3]^2 + ...$. Since squares are always positive regardless of the original sign, we want large squares at even indices (positive contribution) and small squares at odd indices (negative contribution). +The goal is to rearrange the array to maximize the alternating sum of squares: `arr[0]^2 - arr[1]^2 + arr[2]^2 - arr[3]^2 + ...` -**1.3 Brute force vs. optimized strategy:** +Since we can rearrange freely, we want to assign the largest squared values to positions that contribute positively (even indices) and the smallest squared values to positions that contribute negatively (odd indices). -- **Brute Force:** Try all possible rearrangements and calculate the score. This is $O(n!)$ time. -- **Optimized Strategy:** Sort numbers by absolute value in descending order. Assign largest numbers to even indices and smallest to odd indices. This is $O(n \log n)$ time. -- **Why optimized is better:** The greedy assignment maximizes positive contributions and minimizes negative contributions, giving the optimal result. +**1.3 Brute force vs. optimized strategy** -**1.4 Decomposition:** + * **Brute Force:** Try all possible permutations of the array and calculate the alternating sum for each, then take the maximum. This would be O(n! * n), which is infeasible for large inputs. + * **Optimized Strategy:** Since squares are always non-negative, we can sort the squares in descending order. Then we assign the largest squares to positive positions (even indices) and the smallest squares to negative positions (odd indices). This greedy approach is optimal and runs in O(n log n). -1. Convert all numbers to absolute values (since squares are same for positive/negative). -2. Sort in descending order. -3. Assign numbers to positions: even indices get largest numbers, odd indices get smallest numbers. -4. Calculate alternating sum of squares. -5. Return the result. +**1.4 Decomposition** -### Steps (The "How") +1. Calculate the square of each element in the array. +2. Sort the squares in descending order. +3. Count how many positive positions (even indices) and negative positions (odd indices) we have. +4. Assign the largest squares to positive positions and the smallest squares to negative positions. +5. Calculate and return the alternating sum. -**2.1 Initialization & Example Setup:** +### Steps -Let's use the example: `nums = [1,2,3]` +**2.1 Initialization & Example Setup** -We convert to absolute values and sort: `[3,2,1]` +Let's use the example `nums = [1, 2, 3]` to trace through the solution. -**2.2 Start Checking:** +First, we calculate squares: `[1, 4, 9]`. -We assign numbers to positions and calculate the score. +**2.2 Start Checking/Processing** -**2.3 Trace Walkthrough:** +We sort the squares in descending order: `[9, 4, 1]`. -| Index | Assigned Value | Square | Contribution | -|-------|----------------|--------|--------------| -| 0 (even) | 3 | 9 | +9 | -| 1 (odd) | 2 | 4 | -4 | -| 2 (even) | 1 | 1 | +1 | -| Total | | | 9 - 4 + 1 = 6 | +**2.3 Trace Walkthrough** -Wait, let me recalculate. The problem says we can rearrange, so for [1,2,3]: -- Best arrangement: [2,1,3] gives $2^2 - 1^2 + 3^2 = 4 - 1 + 9 = 12$ +For `n = 3`, we have: +- Positive positions (even indices): positions 0 and 2 → 2 positions +- Negative positions (odd indices): position 1 → 1 position -Actually, we want: even positions get largest, odd get smallest. -- [3,1,2]: $3^2 - 1^2 + 2^2 = 9 - 1 + 4 = 12$ ✓ +| Sorted Squares | Position Type | Assignment | Contribution | +|----------------|---------------|------------|--------------| +| 9 | Positive (index 0) | 9 | +9 | +| 4 | Positive (index 2) | 4 | +4 | +| 1 | Negative (index 1) | 1 | -1 | -**2.4 Increment and Loop:** +**2.4 Increment and Loop** -- Sort by absolute value descending: `nums_sorted = sorted([abs(x) for x in nums], reverse=True)` -- Calculate: `for i in range(n): if i % 2 == 0: res += nums_sorted[i]^2 else: res -= nums_sorted[i]^2` +We assign the largest squares to positive positions and smallest to negative positions. The calculation is: `sum([9, 4]) - sum([1]) = 13 - 1 = 12`. -**2.5 Return Result:** - -For `nums = [1,2,3]`, sorted by absolute value: `[3,2,1]`. Arrangement `[3,1,2]` gives score $3^2 - 1^2 + 2^2 = 9 - 1 + 4 = 12$. We return `12`. +**2.5 Return Result** +The maximum alternating sum is `12`, which we return as the final result. diff --git a/explanations/3759/en.md b/explanations/3759/en.md index 35ed0c7..53a4042 100644 --- a/explanations/3759/en.md +++ b/explanations/3759/en.md @@ -1,59 +1,58 @@ ## Explanation -### Strategy (The "Why") +### Strategy -**Restate the problem:** We need to convert string `source` to `target` with minimum cost. We can change characters using given conversion rules, and we can use intermediate characters to reduce cost. +**1.1 Constraints & Complexity** -**1.1 Constraints & Complexity:** -- Input size: `1 <= source.length == target.length <= 10^5`, `1 <= cost.length <= 2000` -- **Time Complexity:** O(26³ + n) = O(n) where n is string length, as Floyd-Warshall on 26 nodes is constant -- **Space Complexity:** O(26²) = O(1) for the distance matrix -- **Edge Case:** If source[i] == target[i], no conversion needed for that position + * **Input Size:** The array `nums` has length `n` where `1 <= n <= 10^5`. Values range from `1` to `10^9`, and `0 <= k < n`. + * **Time Complexity:** O(n log n) - We sort the array once, then iterate through distinct values using binary search, which is O(n log n) overall. + * **Space Complexity:** O(n) - We create a sorted copy of the array. + * **Edge Case:** If `k = 0`, all elements except the maximum are qualified. If all elements are equal, no element is qualified. -**1.2 High-level approach:** -We model character conversions as a graph where edges represent direct conversions with costs. We use Floyd-Warshall to find shortest paths between all character pairs, then sum up the minimum costs for each position. +**1.2 High-level approach** -![Graph shortest path visualization](https://assets.leetcode.com/static_assets/others/graph-shortest-path.png) +The goal is to count how many elements have at least `k` elements strictly greater than them. -**1.3 Brute force vs. optimized strategy:** -- **Brute Force:** Try all possible conversion sequences, which is exponential. -- **Optimized Strategy:** Use Floyd-Warshall to precompute shortest paths between all character pairs in O(26³) time, then use these in O(n) time to compute total cost. +We sort the array first, which allows us to efficiently determine how many elements are greater than any given value. For each distinct value, we count how many elements are strictly greater, and if that count is at least `k`, we add all occurrences of that value to our result. -**1.4 Decomposition:** -1. Build a graph with 26 nodes (characters) and edges from conversion rules -2. Use Floyd-Warshall algorithm to find shortest paths between all pairs -3. For each position, if characters differ, use the shortest path cost -4. Return total cost, or -1 if any conversion is impossible +**1.3 Brute force vs. optimized strategy** -### Steps (The "How") + * **Brute Force:** For each element, count how many other elements are strictly greater by comparing with all other elements. This takes O(n^2) time. + * **Optimized Strategy:** Sort the array first. Then for each distinct value, use binary search to find the first element strictly greater than it. The number of greater elements is `n - upper_bound_index`. This reduces the time complexity to O(n log n). -**2.1 Initialization & Example Setup:** -Let's use the example: `source = "abcd"`, `target = "acbe"`, `original = ["a","b","c","c","e","d"]`, `changed = ["b","c","b","e","b","e"]`, `cost = [2,5,5,1,2,20]` -- Initialize distance matrix with INF, diagonal with 0 -- Add edges: a→b(2), b→c(5), c→b(5), c→e(1), e→b(2), d→e(20) +**1.4 Decomposition** -**2.2 Start Checking:** -We run Floyd-Warshall to compute shortest paths, then process each character position. +1. Sort the array to enable efficient binary search. +2. Iterate through distinct values in the sorted array. +3. For each distinct value, count its occurrences. +4. Use binary search to find the first element strictly greater than the current value. +5. If the number of greater elements is at least `k`, add the count of current value to the result. +6. Move to the next distinct value and repeat. -**2.3 Trace Walkthrough:** -After Floyd-Warshall, key shortest paths: -- a→c: a→b(2) + b→c(5) = 7, or a→b(2) + b→c(5) = 7 -- b→e: b→c(5) + c→e(1) = 6 -- d→e: d→e(20) = 20 +### Steps -Processing `source = "abcd"` to `target = "acbe"`: +**2.1 Initialization & Example Setup** -| Index | source[i] | target[i] | Same? | Conversion | Cost | Total | -|-------|-----------|-----------|-------|------------|------|-------| -| 0 | 'a' | 'a' | Yes | None | 0 | 0 | -| 1 | 'b' | 'c' | No | b→c | 5 | 5 | -| 2 | 'c' | 'b' | No | c→b | 5 | 10 | -| 3 | 'd' | 'e' | No | d→e | 20 | 30 | +Let's use the example `nums = [3, 1, 2]`, `k = 1` to trace through the solution. -Wait, let's recalculate: b→c costs 5, c→b costs 5, but we can also do c→e(1) then e→b(2) = 3, which is better. So c→b = 3. +We sort the array: `sorted_nums = [1, 2, 3]`, and initialize `res = 0`. -**2.4 Increment and Loop:** -For each position, we look up the shortest path cost in our precomputed matrix and add it to the total. +**2.2 Start Checking/Processing** -**2.5 Return Result:** -The total cost is 0 + 5 + 3 + 20 = 28, which is the minimum cost to convert "abcd" to "acbe". +We iterate through distinct values, starting with the smallest value `1` at index 0. + +**2.3 Trace Walkthrough** + +| Current Value | Count | Upper Bound Search | Greater Count | >= k? | Add to res? | res | +|---------------|-------|-------------------|---------------|-------|-------------|-----| +| 1 (index 0) | 1 | Binary search finds first > 1 at index 1 | 3 - 1 = 2 | Yes (2 >= 1) | Yes, add 1 | 1 | +| 2 (index 1) | 1 | Binary search finds first > 2 at index 2 | 3 - 2 = 1 | Yes (1 >= 1) | Yes, add 1 | 2 | +| 3 (index 2) | 1 | Binary search finds first > 3 (none) | 3 - 3 = 0 | No (0 < 1) | No | 2 | + +**2.4 Increment and Loop** + +After processing each distinct value, we move to the next distinct value by skipping all occurrences of the current value. + +**2.5 Return Result** + +The final result is `2`, meaning 2 elements (1 and 2) have at least `k = 1` element strictly greater than them. diff --git a/solutions/3722/01.py b/solutions/3722/01.py index 137df1c..e2ab632 100644 --- a/solutions/3722/01.py +++ b/solutions/3722/01.py @@ -1,21 +1,22 @@ class Solution: def lexSmallest(self, s: str) -> str: n = len(s) - res = s # Start with original string + res = s - # Try reversing first k characters for k from 1 to n + # Try reversing first k characters for all k from 1 to n for k in range(1, n + 1): # Reverse first k characters - reversed_str = s[:k][::-1] + s[k:] - if reversed_str < res: - res = reversed_str + reversed_prefix = s[:k][::-1] + candidate = reversed_prefix + s[k:] + if candidate < res: + res = candidate - # Try reversing last k characters for k from 1 to n + # Try reversing last k characters for all k from 1 to n for k in range(1, n + 1): # Reverse last k characters - reversed_str = s[:n-k] + s[n-k:][::-1] - if reversed_str < res: - res = reversed_str + reversed_suffix = s[n - k:][::-1] + candidate = s[:n - k] + reversed_suffix + if candidate < res: + res = candidate return res - diff --git a/solutions/3727/01.py b/solutions/3727/01.py index 3a7236f..d24a045 100644 --- a/solutions/3727/01.py +++ b/solutions/3727/01.py @@ -1,24 +1,21 @@ +from typing import List + class Solution: def maxAlternatingSum(self, nums: List[int]) -> int: - # Since we're using squares, the sign of original numbers doesn't matter - # We want to maximize: arr[0]^2 - arr[1]^2 + arr[2]^2 - arr[3]^2 + ... - # This means we want large squares at even indices and small squares at odd indices + # Since we can rearrange, we want to maximize the alternating sum + # The pattern is: +a^2 - b^2 + c^2 - d^2 + ... + # We need to assign numbers to positive (even index) and negative (odd index) positions + # To maximize: put largest squares in positive positions, smallest squares in negative positions - # Sort numbers by absolute value (squares are same for positive/negative) - nums_sorted = sorted([abs(x) for x in nums], reverse=True) + n = len(nums) + squares = [x * x for x in nums] + squares.sort(reverse=True) - n = len(nums_sorted) - res = 0 + # Count how many positive and negative positions we have + num_positive = (n + 1) // 2 # Even indices: 0, 2, 4, ... + num_negative = n // 2 # Odd indices: 1, 3, 5, ... - # Assign largest numbers to even indices (positive contribution) - # and smallest numbers to odd indices (negative contribution) - for i in range(n): - if i % 2 == 0: - # Even index: add square - res += nums_sorted[i] * nums_sorted[i] - else: - # Odd index: subtract square - res -= nums_sorted[i] * nums_sorted[i] + # Assign largest squares to positive positions, smallest to negative + res = sum(squares[:num_positive]) - sum(squares[num_positive:]) return res - diff --git a/solutions/3759/01.py b/solutions/3759/01.py index 02b9e45..5ce0d5a 100644 --- a/solutions/3759/01.py +++ b/solutions/3759/01.py @@ -1,41 +1,38 @@ +from typing import List + class Solution: - def minimumCost(self, source: str, target: str, original: List[str], changed: List[str], cost: List[int]) -> int: - # Build graph: character -> character with cost - # Use Floyd-Warshall to find shortest path between all pairs - INF = float('inf') - dist = [[INF] * 26 for _ in range(26)] + def countElements(self, nums: List[int], k: int) -> int: + # Sort the array + sorted_nums = sorted(nums) + n = len(sorted_nums) - # Initialize: same character costs 0 - for i in range(26): - dist[i][i] = 0 - - # Add edges from original to changed - for i in range(len(original)): - orig_char = ord(original[i]) - ord('a') - changed_char = ord(changed[i]) - ord('a') - cost_val = cost[i] - # Keep minimum cost if multiple edges exist - dist[orig_char][changed_char] = min(dist[orig_char][changed_char], cost_val) - - # Floyd-Warshall algorithm - for k in range(26): - for i in range(26): - for j in range(26): - if dist[i][k] != INF and dist[k][j] != INF: - dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]) - - # Calculate total cost res = 0 - for i in range(len(source)): - src_char = ord(source[i]) - ord('a') - tgt_char = ord(target[i]) - ord('a') + + # For each distinct value, count how many elements are strictly greater + i = 0 + while i < n: + # Count occurrences of current value + count = 1 + while i + count < n and sorted_nums[i] == sorted_nums[i + count]: + count += 1 + + # Find the first index with value strictly greater than current + # Use binary search to find upper bound + left, right = i + count, n + while left < right: + mid = (left + right) // 2 + if sorted_nums[mid] > sorted_nums[i]: + right = mid + else: + left = mid + 1 - if src_char == tgt_char: - continue + # Number of elements strictly greater + greater_count = n - left - if dist[src_char][tgt_char] == INF: - return -1 + # If at least k elements are greater, add count to result + if greater_count >= k: + res += count - res += dist[src_char][tgt_char] + i += count return res