Skip to content

Commit ac70ccd

Browse files
Merge pull request #17 from paxtonfitzpatrick/main
solutions and notes for problems 1518 and 1550
2 parents d16199c + b05a483 commit ac70ccd

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

problems/1518/paxtonfitzpatrick.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# [Problem 1518: Water Bottles](https://leetcode.com/problems/water-bottles)
2+
3+
## Initial thoughts (stream-of-consciousness)
4+
5+
- seems pretty simple...
6+
- when exchanging empties for fulls, will need to use floor division to figure out how many fulls we can get and also modulo to figure out how many empties couldn't be echanged
7+
- also need to keep track of unexchanged empties in case we can accumulate enough for another full (`numExchange`)
8+
- stop when we have no more fulls and not enough empties to exchange for a full
9+
- I think I'll structure this as a `while` loop where each time through the loop we can drink fulls and/or exchange empties
10+
- There's probably a more efficient way to do this without looping, where we calculate everything from the initial values (so, $O(1)$), but this seems like an easier place to start.
11+
- I bet there's also a way to set this up recursively, which could be interesting, but unlikely to be optimal
12+
13+
## Refining the problem, round 2 thoughts
14+
15+
- Version 2: I noticed some small tweaks I could make to the logic that I think would speed up the `while` loop version slightly
16+
- note: key to not having to modify `n_empties` twice each iteration is updating `n_fulls` and `n_empties` simultaneously. New values for both variables depend on the old value of the other, so updating both on the same line ensures both calculations use the "old" values. Could also have stored `n_empties + n_fulls` in a temporary variable, but that would've taken a teeny bit more time & memory.
17+
18+
## Attempted solution(s)
19+
20+
Version 1:
21+
22+
```python
23+
class Solution:
24+
def numWaterBottles(self, numBottles: int, numExchange: int) -> int:
25+
n_fulls = numBottles
26+
n_empties = 0
27+
n_drank = 0
28+
while True:
29+
n_drank += n_fulls
30+
n_empties += n_fulls
31+
if n_empties < numExchange:
32+
return n_drank
33+
n_fulls = n_empties // numExchange
34+
n_empties = n_empties % numExchange
35+
```
36+
37+
![Version 1 results](https://github.com/paxtonfitzpatrick/leetcode-solutions/assets/26118297/08d502ae-a947-49fc-89a9-fb578ea937a6)
38+
39+
Version 2:
40+
41+
```python
42+
class Solution:
43+
def numWaterBottles(self, numBottles: int, numExchange: int) -> int:
44+
n_drank = numBottles
45+
n_fulls = numBottles // numExchange
46+
n_empties = numBottles % numExchange
47+
while n_fulls > 0:
48+
n_drank += n_fulls
49+
n_fulls, n_empties = (n_empties + n_fulls) // numExchange, (n_empties + n_fulls) % numExchange
50+
return n_drank
51+
```
52+
53+
![Version 2 results](https://github.com/paxtonfitzpatrick/leetcode-solutions/assets/26118297/ba0ca272-8761-4cc5-9c2f-9deb12d40361)
54+
Appears to be slower than version 1, but probably just due to random variation runtime of the test cases. Pretty confident that in reality, version 2 is marginally faster.

problems/1550/paxtonfitzpatrick.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# [Problem 1550: Three Consecutive Odds](https://leetcode.com/problems/three-consecutive-odds/description/)
2+
3+
## Initial thoughts (stream-of-consciousness)
4+
5+
- seems like a pretty easy one
6+
- need to track the number of consecutive odds
7+
- if counter ever reaches 3, return True
8+
- if we encounter an even number, reset counter to 0
9+
10+
## Refining the problem
11+
12+
- I bet this will ultimately be slower, but I can think of a kinda fun, roundabout way solve this:
13+
- convert `arr` to a string
14+
- use regular expression to search for 3 consecutive occurrences of values that end in 1, 3, 5, 7, or 9, separated by a command and space
15+
- we know that all values are <= 1000, and 1000 is an even number, so all odd numbers will have 1, 2, or 3 digits -- so for each number we need to match 0, 1, or 2 digits of any value, followed by an odd digit: `[0-9]{0,2}[13579]`
16+
- base pattern would be `(?:[0-9]{0,2}[13579], ){3}` but:
17+
- this would fail for the last 3 values in the list because there's no trailing comma. So instead use `(?:[0-9]{0,2}[13579], ){2}[0-9]{0,2}[13579]`
18+
- Also for the first of the 3 odd numbers, we should only try to match the final digit rather than all digits, otherwise the search will be slower because the pattern will initially match all values in the list and waste a bunch of time backtracking. So instead use `[13579], [0-9]{0,2}[13579], [0-9]{0,2}[13579]` or `[13579](?:, [0-9]{0,2}[13579]){2}`
19+
20+
- `re.search` returns a `Match` object as soon as it encounters the first match, and `None` if no match is found. So we should be able to just `bool()` the result and return it.
21+
- I wonder if compiling the pattern upfront would be faster than using using the module-level functions... depends on how leetcode runs the test cases, I guess. If I compile the expression in the class body outside the method definition, and all test case runs reuse the same instance of the class, then it should save time. Otherwise, it probably wouldn't. Maybe I'll just compile it in the global namespace and see.
22+
23+
## Attempted solution(s)
24+
25+
```python
26+
class Solution:
27+
def threeConsecutiveOdds(self, arr: List[int]) -> bool:
28+
if len(arr) < 3:
29+
return False
30+
31+
consec_odds = 0
32+
for val in arr:
33+
if val % 2:
34+
if consec_odds == 2:
35+
return True
36+
consec_odds += 1
37+
else:
38+
consec_odds = 0
39+
return False
40+
```
41+
42+
![](https://github.com/paxtonfitzpatrick/leetcode-solutions/assets/26118297/c45d108c-b23b-48d8-bc14-13a2cdc0cc06)
43+
44+
```python
45+
from re import compile
46+
47+
pattern = compile(r"[13579](?:, [0-9]{0,2}[13579]){2}")
48+
49+
class Solution:
50+
def threeConsecutiveOdds(self, arr: List[int]) -> bool:
51+
return bool(pattern.search(str(arr)))
52+
```
53+
54+
![](https://github.com/paxtonfitzpatrick/leetcode-solutions/assets/26118297/88d07bb2-f252-4797-81e4-33793acaeae4)

0 commit comments

Comments
 (0)