Skip to content

Commit 34d9a45

Browse files
Solved 719!
1 parent d1b6fea commit 34d9a45

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

problems/719/jeremymanning.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,50 @@ class Solution:
167167
💩!
168168

169169
Ugh. I'm going to need to come back to this 😞...too tired to think!
170+
171+
## The next day...
172+
- I've now gone through this code many times. I think it's *very close* to being right, but I think that I'm missing one or more important edge cases.
173+
- I think the heap-based approach may actually be over-complicating the problem. Instead, what if we think this through in a different way:
174+
- Let's start by sorting `nums`. This is cheap ($O(n \log n)$, where $n$ is `len(nums)`) and will almost certainly make the problem easier. The *maximum* distance is now `nums[-1] - nums[0]`. The *minimum* distance (if we have any repeats) is 0. Note: we might need to actually *see* if we have any repeats. We'll come back to this.
175+
- What if we do a sort of "binary search" approach? Something like:
176+
- Set `left, right = 0, nums[-1] - nums[0]`. Note: again, I'm not sure if `left` is set correctly. Come back to this...
177+
- Now find the midpoint. This is just `mid = (left + right) // 2`.
178+
- Now we have to find the "rank" of `mid` in the distances. To do this:
179+
- For each index `i` in `range(len(nums))`:
180+
- Increment a second counter, `j`, until `nums[j] - nums[i]` grows larger than `mid`.
181+
- Now we can increment a `count` (of the number of distances) by `j - i - 1` -- this tracks how many distances are less than or equal to `mid`.
182+
- After looping through every number in the outer loop, if `count >= k`, then we know that `mid` is too high. So we can set the `right` bound to `mid`. Alternatively, if `count < k`, we know that `mid` is too *low*, so we can set the `left` bound to `mid + 1`. This halves our search space with each iteration of the outermost loop.
183+
- Once `left >= right` we should break out of the outer loop and return `left`. This should be exactly equal to the `k`th smallest distance.
184+
- Caveats:
185+
- It's possible the "correction by 1" line (incrementing `count` by `j - i - 1`) is off, and we should instead increment `count` by `j - i`. Let's keep track of this as a possible explanation for why things fail.
186+
- It's possible we should return `right` at the end instead of `left`. Again, let's track this as a possible fail point. We may need to walk through the full thing...
187+
- Let's write this out and test it:
188+
189+
```python
190+
class Solution:
191+
def smallestDistancePair(self, nums: List[int], k: int) -> int:
192+
nums.sort()
193+
left, right = 0, nums[-1] - nums[0]
194+
195+
while left < right:
196+
mid = (left + right) // 2
197+
count = 0
198+
j = 0
199+
for i in range(len(nums)):
200+
while j < len(nums) and nums[j] - nums[i] <= mid:
201+
j += 1
202+
count += j - i - 1
203+
204+
if count >= k:
205+
right = mid
206+
else:
207+
left = mid + 1
208+
209+
return left
210+
```
211+
- Ok, the test cases + prior "failed" cases are now passing 😳!
212+
- Let's see if this works...submitting!
213+
214+
![Screenshot 2024-08-14 at 11 30 46 PM](https://github.com/user-attachments/assets/0c978101-8180-4533-ad74-1d86c0784036)
215+
216+
Finally!! 🥳! Actually, that approach was way simpler than the heap idea 🤦.

0 commit comments

Comments
 (0)