forked from ls1248659692/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdict_examples.py
More file actions
348 lines (290 loc) · 10.9 KB
/
Copy pathdict_examples.py
File metadata and controls
348 lines (290 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
from collections import defaultdict
from collections import Counter
from operator import eq
# [1] https://leetcode.com/problems/two-sum/
# Given an array of integers, return indices of the two numbers such that they add up to a specific target.
def twoSum(nums, target):
complement = {}
for i in range(len(nums)):
if nums[i] in complement:
return [complement[nums[i]], i]
else:
complement[target - nums[i]] = i
# [266] https://leetcode.com/problems/palindrome-permutation/
# Given a string, determine if a permutation of the string could form a palindrome.
def canPermutePalindrome1(s: str) -> bool:
return len([count for count in Counter(s).values() if count % 2 == 1]) <= 1
def canPermutePalindrome2(s: str) -> bool:
return len(list(filter(lambda x: x % 2, Counter(s).values()))) <= 1
def canPermutePalindrome3(s: str) -> bool:
return sum(1 for _ in filter(lambda x: x % 2, Counter(s).values())) <= 1
def canPermutePalindrome4(s: str) -> bool:
return sum(v % 2 for v in Counter(s).values()) < 2
# [49] https://leetcode.com/problems/group-anagrams/
# Given an array of strings, group anagrams together.
#
# categorize by sorted string
def groupAnagrams1(strs):
ans = defaultdict(list)
for s in strs:
ans[tuple(sorted(s))].append(s)
return ans.values()
# [49] https://leetcode.com/problems/group-anagrams/
# Given an array of strings, group anagrams together.
#
# categorize by count
def groupAnagrams2(strs):
ans = defaultdict(list)
for s in strs:
count = [0] * 26
for c in s:
count[ord(c) - ord('a')] += 1
ans[tuple(count)].append(s)
return list(ans.values())
# [36] https://leetcode.com/problems/valid-sudoku
# Determine if a 9x9 Sudoku board is valid.
def isValidSudoku1(board):
row_counters = [{} for _ in range(9)]
col_counters = [{} for _ in range(9)]
box_counters = [{} for _ in range(9)]
for r_i, row in enumerate(board):
for c_i, v in enumerate(row):
if v.isdigit():
num = int(v) - 1
box_i = r_i // 3 * 3 + c_i // 3
if num not in row_counters[r_i] and num not in col_counters[c_i] \
and num not in box_counters[box_i]:
row_counters[r_i][num] = 1
col_counters[c_i][num] = 1
box_counters[box_i][num] = 1
else:
return False
return True
# [170] https://leetcode.com/problems/two-sum-iii-data-structure-design/
# Design and implement a TwoSum class. It should support the following operations: add and find.
class TwoSum2:
def __init__(self):
self.data = {}
self.sum = set()
self.max = float('-inf')
self.min = float('inf')
def add(self, number):
if number in self.data:
self.data[number] += 1
else:
self.data[number] = 1
self.max = max(self.max, number)
self.min = min(self.min, number)
def find(self, value):
if value > 2 * self.max or value < 2 * self.min:
return False
if value in self.sum:
return True
for k in self.data.keys():
if (value - k != k and value - k in self.data) or (value - k == k and self.data[k] > 1):
self.sum.add(value)
return True
return False
# [311] https://leetcode.com/problems/sparse-matrix-multiplication/
# Given two sparse matrices A and B, return the result of AB.
def multiply(A, B):
m, n = len(A), len(B[0])
a_rows = []
for rows in A:
a_rows.append({col: v for col, v in enumerate(rows) if v != 0})
b_cols = []
for j in range(n):
b_cols.append({i: B[i][j] for i in range(len(B)) if B[i][j] != 0})
res = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
for k, v in a_rows[i].items():
if k in b_cols[j]:
res[i][j] += v * b_cols[j][k]
return res
# [325] https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/
# Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead.
def maxSubArrayLen(nums, k):
ans, acc = 0, 0 # answer and the accumulative value of nums
mp = {0: -1} # key is acc value, and value is the index
for i in range(len(nums)):
acc += nums[i]
# if already exits in mp, only keep the shortest, that is the first one. it solves duplication problem.
if acc not in mp:
mp[acc] = i
if acc - k in mp:
ans = max(ans, i - mp[acc - k])
return ans
# [350] https://leetcode.com/problems/intersection-of-two-arrays-ii/
# Given two arrays, write a function to compute their intersection.
#
# use two Counter intersection
def intersect(nums1, nums2):
a, b = map(Counter, (nums1, nums2))
return list((a & b).elements())
# [350] https://leetcode.com/problems/intersection-of-two-arrays-ii/
# Given two arrays, write a function to compute their intersection.
#
# use one Counter
def intersect2(nums1, nums2):
# choose the smaller list as Counter
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
cnt, res = Counter(nums1), []
for num in nums2:
if num in cnt and cnt[num] > 0:
res.append(num)
cnt[num] -= 1
return res
# [560] https://leetcode.com/problems/subarray-sum-equals-k/
# Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.
def subarraySum(nums: 'List[int]', k: 'int') -> 'int':
count, cur_sum = 0, 0
mapping = defaultdict(int)
mapping[0] = 1
for i in range(len(nums)):
cur_sum += nums[i]
if cur_sum - k in mapping:
count += mapping[cur_sum - k]
mapping[cur_sum] += 1
return count
# [359] https://leetcode.com/problems/logger-rate-limiter/
# Given a message and a timestamp (in seconds granularity), return true if the message should be printed in the given
# timestamp, otherwise returns false.
class Logger:
def __init__(self):
self.mem = {}
def shouldPrintMessage(self, timestamp: int, message: str) -> bool:
if message not in self.mem or timestamp >= self.mem[message]:
self.mem[message] = timestamp + 10
return True
return False
# [299] https://leetcode.com/problems/bulls-and-cows/
# Write a function to return a hint according to the secret number and friend's guess,
# use A to indicate the bulls and B to indicate the cows.
def getHint1(secret, guess):
bulls = sum(map(eq, secret, guess))
both = sum(min(secret.count(x), guess.count(x)) for x in set(guess))
return '%dA%dB' % (bulls, both - bulls)
# & in counter
def getHint2(secret, guess):
A = sum(a == b for a, b in zip(secret, guess))
B = Counter(secret) & Counter(guess)
return "%dA%dB" % (A, sum(B.values()) - A)
# One Pass solution
def getHint3(secret, guess):
# use arr instead of dict, but slow than it
counter = [0] * 10
bulls, cows = 0, 0
for i, (s, g) in enumerate(zip(secret, guess)):
if s == g:
bulls += 1
else:
s_i, g_i = ord(s) - ord('0'), ord(g) - ord('0')
if counter[s_i] < 0: cows += 1
if counter[g_i] > 0: cows += 1
counter[s_i] += 1
counter[g_i] -= 1
return f'{bulls}A{cows}B'
# [362] https://leetcode.com/problems/design-hit-counter/
# Design a hit counter which counts the number of hits received in the past 5 minutes.
#
# loop list, dict, bisect, bucket
# depends on the data dense and amount
#
# dict solution
class HitCounter1:
def __init__(self):
"""
Initialize your data structure here.
"""
self.hits = defaultdict(int)
def hit(self, timestamp: 'int') -> 'None':
"""
Record a hit.
@param timestamp - The current timestamp (in seconds granularity).
"""
if timestamp in self.hits:
self.hits[timestamp] += 1
else:
self.hits[timestamp] = 1
# 定时清理
# past = [ts for ts in self.hits if ts < timestamp - 300]
# for ts in past:
# del self.hits[ts]
def getHits(self, timestamp: 'int') -> 'int':
"""
Return the number of hits in the past 5 minutes.
@param timestamp - The current timestamp (in seconds granularity).
"""
return sum(self.hits[ts] for ts in range(timestamp, timestamp - 300, -1) if ts > 0)
# [362] https://leetcode.com/problems/design-hit-counter/
# Design a hit counter which counts the number of hits received in the past 5 minutes.
#
# bisect queue
class HitCounter2:
def __init__(self):
"""
Initialize your data structure here.
"""
self.timed_counter = [[0, 0]]
def hit(self, timestamp: 'int') -> 'None':
"""
Record a hit.
@param timestamp - The current timestamp (in seconds granularity).
"""
if self.timed_counter[-1][0] == timestamp:
self.timed_counter[-1][1] += 1
else:
prev_count = self.timed_counter[-1][1]
self.timed_counter.append([timestamp, prev_count + 1])
def getHits(self, timestamp: 'int') -> 'int':
"""
Return the number of hits in the past 5 minutes.
@param timestamp - The current timestamp (in seconds granularity).
"""
t_begin, t_end = timestamp - 300, timestamp
c_begin, c_end = self._search(t_begin), self._search(t_end)
return c_end - c_begin
def _search(self, ts):
i, j = 0, len(self.timed_counter),
k = -1
while i < j:
k = (i + j) // 2
if self.timed_counter[k][0] > ts:
j = k
elif self.timed_counter[k][0] < ts:
i = k + 1
else:
break
else:
k = i - 1
if k < 0:
return 0
else:
return self.timed_counter[k][1]
# [362] https://leetcode.com/problems/design-hit-counter/
# Design a hit counter which counts the number of hits received in the past 5 minutes.
#
# bucket solution
class HitCounter3:
def __init__(self):
self.window_size = 300
self.buckets = [None] * self.window_size
def hit(self, timestamp):
index = timestamp % self.window_size
if self.buckets[index] is None:
self.buckets[index] = [timestamp, 1]
return
old_time, old_count = self.buckets[index]
if old_time < timestamp:
self.total -= old_count
self.buckets[index] = [timestamp, 1]
else: # old time is equal to the timestamp
self.buckets[index][1] += 1
def getHits(self, timestamp):
total = 0
for bt in self.buckets:
if bt and timestamp - bt[0] < self.window_size:
total += bt[1]
return total