Skip to content

Commit c9d5bbb

Browse files
committed
move problems in notebooks to leetcode dir
1 parent 87c8641 commit c9d5bbb

File tree

11 files changed

+320
-328
lines changed

11 files changed

+320
-328
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from collections import Counter
2+
from typing import List
3+
4+
5+
class Solution:
6+
def carPooling(self, trips: List[List[int]], capacity: int) -> bool:
7+
first, last = float('inf'), -float('inf')
8+
stops = Counter()
9+
for passengers, start, end in trips:
10+
stops[start] += passengers
11+
stops[end] -= passengers
12+
first = min(first, start)
13+
last = max(last, end)
14+
15+
seats = 0
16+
for i in range(first, last+1):
17+
seats += stops[i]
18+
if seats > capacity:
19+
return False
20+
return True
21+
22+
23+
s = Solution()
24+
cases = [
25+
([[2, 1, 5], [3, 3, 7]], 4, False),
26+
([[2, 1, 5], [3, 3, 7]], 5, True),
27+
([[2, 1, 5], [3, 5, 7]], 3, True),
28+
([[3, 2, 7], [3, 7, 9], [8, 3, 9]], 11, True),
29+
]
30+
31+
for trips, capacity, expected in cases:
32+
actual = s.carPooling(trips, capacity)
33+
assert actual == expected, f"{trips, capacity}: {expected} != {actual}"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from typing import List
2+
3+
4+
class Solution:
5+
def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:
6+
flights = [0] * (n+1)
7+
for first, last, count in bookings:
8+
flights[first-1] += count
9+
flights[last] -= count
10+
for i in range(1, n):
11+
flights[i] += flights[i-1]
12+
return flights[:-1]
13+
14+
15+
s = Solution()
16+
cases = [
17+
([[1, 2, 10], [2, 3, 20], [2, 5, 25]], 5, [10, 55, 45, 25, 25])
18+
]
19+
for bookings, n, expected in cases:
20+
actual = s.corpFlightBookings(bookings, n)
21+
assert actual == expected, f"{bookings, n}: {expected} != {actual}"
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from collections import Counter
2+
from typing import List
3+
4+
5+
def interval_sweep_shitty(requests):
6+
"""
7+
Given a list of ranges, return an array
8+
where arr[i] equals the number of ranges
9+
including i.
10+
"""
11+
bounds_counts = Counter()
12+
first, last = float('inf'), -float('inf')
13+
for start, end in requests:
14+
bounds_counts[start] += 1
15+
bounds_counts[end+1] -= 1
16+
first = min(start, end, first)
17+
last = max(start, end, last)
18+
19+
frequency = 0
20+
overlap_count = []
21+
for val in range(first, last+1):
22+
frequency += bounds_counts[val]
23+
overlap_count.append(frequency)
24+
return overlap_count
25+
26+
27+
def interval_sweep(nums_len, requests):
28+
"""
29+
Same as above, but borrowing from @lee215's
30+
technique which is faster.
31+
"""
32+
counts = [0] * (nums_len+1)
33+
for start, end in requests:
34+
counts[start] += 1
35+
counts[end+1] -= 1
36+
37+
for i in range(1, nums_len+1):
38+
counts[i] += counts[i-1]
39+
return counts
40+
41+
42+
class Solution:
43+
def maxSumRangeQuery(self, nums: List[int], requests: List[List[int]]) -> int:
44+
nums.sort(reverse=True)
45+
overlap_count = interval_sweep(len(nums), requests)
46+
max_sum = 0
47+
for i, frequency in enumerate(sorted(overlap_count[:-1], reverse=True)):
48+
max_sum += frequency*nums[i]
49+
return max_sum % (10**9 + 7)
50+
51+
52+
s = Solution()
53+
cases = [
54+
([1, 2, 3, 4, 5], [[1, 3], [0, 1]], 19),
55+
([1, 2, 3, 4, 5, 6], [[0, 1]], 11),
56+
([1, 2, 3, 4, 5, 10], [[0, 2], [1, 3], [1, 1]], 47)
57+
]
58+
for nums, requests, expected in cases:
59+
actual = s.maxSumRangeQuery(nums, requests)
60+
assert actual == expected, f"{nums, requests}: {expected} != {actual}"
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.is_leaf = False
5+
6+
7+
class WordDictionary:
8+
def __init__(self):
9+
"""
10+
Initialize your data structure here.
11+
"""
12+
self.root = TrieNode()
13+
14+
def addWord(self, word: str) -> None:
15+
node = self.root
16+
for letter in word:
17+
if letter in node.children:
18+
node = node.children[letter]
19+
else:
20+
new_node = TrieNode()
21+
node.children[letter] = new_node
22+
node = new_node
23+
node.is_leaf = True
24+
25+
def _search(self, word, i, node):
26+
if i == len(word):
27+
return node.is_leaf
28+
if word[i] == ".":
29+
for child in node.children.values():
30+
if self._search(word, i+1, child):
31+
return True
32+
return False
33+
if word[i] not in node.children:
34+
return False
35+
return self._search(word, i+1, node.children[word[i]])
36+
37+
def search(self, word: str) -> bool:
38+
return self._search(word, 0, self.root)
39+
40+
41+
null, true, false = None, True, False
42+
cases = [
43+
[
44+
["addWord", "addWord", "search", "search", "search", "search", "search", "search", "search", "search"],
45+
[["a"], ["ab"], ["a"], ["a."], ["ab"], [".a"], [".b"], ["ab."], ["."], [".."]],
46+
[null, null, true, true, true, false, true, false, true, true]
47+
]
48+
]
49+
wd = WordDictionary()
50+
for commands, args, expecteds in cases:
51+
for i, _ in enumerate(commands):
52+
command = commands[i]
53+
arg = args[i][0]
54+
expected = expecteds[i]
55+
if command == "addWord":
56+
wd.addWord(arg)
57+
else:
58+
actual = wd.search(arg)
59+
assert expected == actual, f"{command,arg}: {expected} != {actual}"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from typing import List
2+
3+
4+
def binary_search(row, val):
5+
lo, hi = 0, len(row)-1
6+
while lo <= hi:
7+
mid = (hi+lo) // 2
8+
if row[mid] == val:
9+
return mid, True
10+
elif row[mid] < val:
11+
lo = mid + 1
12+
else:
13+
hi = mid - 1
14+
return lo, False
15+
16+
17+
class Solution:
18+
def searchMatrix(self, matrix: List[List[int]], val: int) -> bool:
19+
# List construction here is O(n) and O(m), but we only do each
20+
# once regardless of input size.
21+
lowest_row, found = binary_search([row[-1] for row in matrix], val)
22+
if found:
23+
return found
24+
highest_row, found = binary_search([row[0] for row in matrix], val)
25+
if found:
26+
return found
27+
28+
# if lowest row == 0 and highest row == len(matrix)-1, this becomes
29+
# O(nlog(m)) for n rows and m columns.
30+
for y in range(lowest_row, highest_row):
31+
_, found = binary_search(matrix[y], val)
32+
if found:
33+
return found
34+
35+
return False
36+
37+
38+
cases = [
39+
([[1]], 1, True),
40+
([[6]], 1, False),
41+
([[1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30]], 666, False),
42+
([[1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30]], 5, True),
43+
]
44+
s = Solution()
45+
for matrix, val, expected in cases:
46+
actual = s.searchMatrix(matrix, val)
47+
assert actual == expected, f"{matrix,val}: {expected} != {actual}"
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from collections import deque
2+
from typing import List
3+
4+
5+
class Solution:
6+
def validTree(self, n: int, edges: List[List[int]]) -> bool:
7+
if not edges:
8+
return n < 2
9+
adj_list = {i: set() for i in range(0, n)}
10+
for n1, n2 in edges:
11+
adj_list[n1].add(n2)
12+
adj_list[n2].add(n1)
13+
14+
visited = set()
15+
q = deque([(edges[0][0], None)])
16+
while q:
17+
curr, parent = q.popleft()
18+
visited.add(curr)
19+
for child in adj_list[curr]:
20+
if child == parent:
21+
continue
22+
if child in visited:
23+
return False
24+
q.append((child, curr))
25+
return len(visited) == n
26+
27+
28+
s = Solution()
29+
cases = [
30+
(5, [[0, 1], [0, 2], [0, 3], [1, 4]], True),
31+
(5, [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], False),
32+
]
33+
for n, edges, expected in cases:
34+
actual = s.validTree(n, edges)
35+
assert actual == expected, f"{n, edges}"
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from typing import List
2+
3+
4+
def flipped(bit):
5+
return '0' if bit == '1' else '1'
6+
7+
8+
class Solution:
9+
def findMaximumXOR(self, nums: List[int]) -> int:
10+
root = {}
11+
required = len(bin(max(nums))[2:])
12+
bitstrs = [bin(val)[2:].zfill(required) for val in nums]
13+
for bitstr in bitstrs:
14+
node = root
15+
for bit in bitstr:
16+
if bit not in node:
17+
node[bit] = {}
18+
node = node[bit]
19+
20+
best_xor = 0
21+
for bitstr in bitstrs:
22+
curr_xor = ''
23+
node = root
24+
for bit in bitstr:
25+
next_bit = flipped(bit) if flipped(bit) in node else bit
26+
curr_xor += '1' if next_bit != bit else '0'
27+
node = node[next_bit]
28+
best_xor = max(best_xor, int(curr_xor, 2))
29+
return best_xor
30+
31+
32+
s = Solution()
33+
cases = [
34+
([3, 10, 5, 25, 2, 8], 28),
35+
([0], 0),
36+
([2, 4], 6),
37+
([8, 10, 2], 10),
38+
([14, 70, 53, 83, 49, 91, 36, 80, 92, 51, 66, 70], 127),
39+
([32, 18, 33, 42, 29, 20, 26, 36, 15, 46], 62)
40+
]
41+
for vals, expected in cases:
42+
actual = s.findMaximumXOR(vals)
43+
assert actual == expected, f"{vals}: {expected} != {actual}"

notebooks/Data Structure - Graphs.ipynb

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -76,43 +76,11 @@
7676
},
7777
{
7878
"cell_type": "code",
79-
"execution_count": 18,
79+
"execution_count": 1,
8080
"metadata": {},
8181
"outputs": [],
8282
"source": [
83-
"from collections import deque\n",
84-
"\n",
85-
"class Solution:\n",
86-
" def validTree(self, n: int, edges: List[List[int]]) -> bool:\n",
87-
" if not edges:\n",
88-
" return n < 2\n",
89-
" adj_list = {i:set() for i in range(0, n)}\n",
90-
" for n1,n2 in edges:\n",
91-
" adj_list[n1].add(n2)\n",
92-
" adj_list[n2].add(n1)\n",
93-
" \n",
94-
" visited = set()\n",
95-
" q = deque([(edges[0][0], None)])\n",
96-
" while q:\n",
97-
" curr, parent = q.popleft()\n",
98-
" visited.add(curr)\n",
99-
" for child in adj_list[curr]:\n",
100-
" if child == parent:\n",
101-
" continue\n",
102-
" if child in visited:\n",
103-
" return False\n",
104-
" q.append((child,curr))\n",
105-
" return len(visited) == n\n",
106-
"\n",
107-
"s = Solution()\n",
108-
"cases = [\n",
109-
" (5, [[0,1], [0,2], [0,3], [1,4]], True),\n",
110-
" (5, [[0,1], [1,2], [2,3], [1,3], [1,4]], False),\n",
111-
"]\n",
112-
"for n, edges, expected in cases:\n",
113-
" actual = s.validTree(n, edges)\n",
114-
" assert actual == expected, f\"{n, edges}\"\n",
115-
" "
83+
"%run ../leetcode/261-graph-valid-tree/solution.py"
11684
]
11785
}
11886
],

0 commit comments

Comments
 (0)