def test(input_, want):
= Solution().foo(input_)
got
if got != want:
= f"got='{got}', want='{want}'"
msg raise AssertionError(msg)
longest-substring-without-repeating-characters
https://leetcode.com/problems/longest-substring-without-repeating-characters/
class Solution:
def foo(self, s: str) -> int:
= 0
max_len for idx_start in range(len(s)):
= set()
sub for i in range(idx_start, len(s)):
# print(idx_start, i, s[i], sub)
if s[i] in sub:
# print(len(sub))
= max(max_len, len(sub))
max_len break
else:
|= set(s[i])
sub = max(max_len, len(sub))
max_len
return max_len
"pwwkew", 3)
test(" ", 1)
test("wwww", 1)
test("abcabcbb", 3)
test("", 0)
test("abcdexfbdgcbb", 7) test(
# one-pass sliding window
class Solution:
def foo(self, s: str) -> int:
= len(s)
n = 0
ans
= {} # store max index
mp = 0
i for j in range(n):
if s[j] in mp:
= max(mp[s[j]], i)
i
= max(ans, j - i + 1)
ans = j + 1
mp[s[j]]
return ans
# Time complexity : O(n). Index j will iterate n times.
# Memory: O(min(m, n)) We need O(k) space for the sliding window, where kk is the size of the Set. The size of the Set is upper bounded by the size of the string nn and the size of the charset/alphabet mm.
"abcdexfbdgcbb", 7)
test("pwwkew", 3)
test(" ", 1)
test("wwww", 1)
test("abcabcbb", 3)
test("", 0) test(
7. Reverse Integer
Given a signed 32-bit integer x, return x with its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range \([-2^{31}, 2^{31} - 1]\), then return 0.
Assume the environment does not allow you to store 64-bit integers (signed or unsigned).
class Solution:
def foo(self, x: int) -> int:
= (2**31) - 1
MAX_INT
if x >= 0:
= 1
sign else:
= -1
sign = list()
nums
= abs(x)
x while True:
% 10)
nums.append(x = x // 10
x if x == 0:
# print(nums)
break
= 1
dec = 0
ans for n in nums[::-1]:
# since we use 32bit, we should return 0 if (ans+tail) > MAX_INT
# if we rearrange parts of the eqation, we can avoid overflowing while
# still checking (ans+tail) for overflow
if (ans / MAX_INT + n * (dec / MAX_INT)) > 1:
return 0
+= n * dec
ans *= 10
dec return ans * sign
class Solution:
def foo(self, x: int) -> int:
= (2**31) - 1
MAX_INT
if x >= 0:
= 1
sign else:
= -1
sign = list()
nums
= abs(x)
x while True:
% 10)
nums.append(x = x // 10
x if x == 0:
print(nums)
break
= 1
dec = 0
ans for n in nums[::-1]:
# since we use 32bit, we should return 0 if (ans+tail) > MAX_INT
# if we rearrange parts of the eqation, we can avoid overflowing while
# still checking (ans+tail) for overflow
if (ans / MAX_INT + n * (dec / MAX_INT)) > 1:
return 0
+= n * dec
ans *= 10
dec return ans * sign
1534236469, 0)
test(123, 321)
test(-123, -321)
test(0, 0)
test(120, 21) test(
2**32 - 1
2147483651 >= 2**31
= 321
x = 120
x = -321 x
5. Longest Palindromic Substring
# quadratic solution (too slow)
class Solution:
def foo(self, s):
= len(s)
n
while n:
for i in range(len(s) - n + 1):
= s[i : i + n]
candidate # print(n,i,candidate)
if self.is_palindrome(candidate):
return candidate
-= 1
n
return ""
def is_palindrome(self, x: str) -> bool:
= len(x)
n for i in range(n // 2):
if x[i] != x[n - i - 1]:
return False
return True
class Solution:
def foo(self, s: str) -> str:
= "" # Memory to remember a palindrome
m for i in range(len(s)): # i = start, O = n
for j in range(len(s), i, -1): # j = end, O = n^2
if len(m) >= j - i: # To reduce time
break
elif s[i:j] == s[i:j][::-1]:
= s[i:j]
m break
return m
class Solution:
def foo(self, s: str) -> str:
= "" # Memory to remember a palindrome
m for i in range(len(s)): # i = start, O = n
for j in range(len(s), i, -1): # j = end, O = n^2
if len(m) >= j - i: # To reduce time
break
elif s[i:j] == s[i:j][::-1]:
= s[i:j]
m break
return m
list(range(5, 2, -1))
"babad", "bab")
test(
"cbbd", "bb")
test(
"a", "a")
test(
"", "") test(
def generate(cur, open, closed, n):
if len(cur) == 2 * n:
if open == closed:
print(cur)
return
+ "(", open + 1, closed, n)
generate(cur
if open > closed:
+ ")", open, closed + 1, n) generate(cur
"", 0, 0, 1) generate(
"", 0, 0, 2) generate(
"", 0, 0, 3) generate(
21. Merge Two Sorted Lists
Runtime: 40 ms, faster than 49.45% of Python3 online submissions for Merge Two Sorted Lists.
Memory Usage: 14.3 MB, less than 33.73% of Python3 online submissions for Merge Two Sorted Lists.
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def __repr__(self):
return f"{self.val} -> {self.next}"
class Solution:
def _merge(self, l1, l2):
= self.list_to_ListNode(l1)
l1 = self.list_to_ListNode(l2)
l2
return self.mergeTwoLists(l1, l2)
def list_to_ListNode(self, lst):
= iter(lst)
lst = ListNode(val=next(lst))
root = root
node for newval in lst:
next = ListNode(val=newval)
node.= node.next
node return root
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
# DON'T FORGET TO DROP FIRST NODE
= ListNode(val=None)
answer_root = answer_root
answer
while True:
if (l1 is None) and (l2 is not None):
next = ListNode(l2.val)
answer.= l2.next
l2 elif (l1 is not None) and (l2 is None):
next = ListNode(l1.val)
answer.= l1.next
l1 elif (l1 is None) and (l2 is None):
return answer_root.next # remember to drop fake zero-node
# print(answer_root.next)
elif l1.val <= l2.val:
next = ListNode(l1.val)
answer.= l1.next
l1 elif l1.val > l2.val:
next = ListNode(l2.val)
answer.= l2.next
l2 else:
raise Exception
= answer.next answer
= Solution().list_to_ListNode convert
= [1, 2, 4, 5]
l1 = [2, 3, 4]
l2
# print(Solution().list_to_ListNode(l1))
# print(Solution().list_to_ListNode(l2))
= convert(l1), convert(l2)
l1, l2 print(l1)
print(l2)
# DON'T FORGET TO DROP FIRST NODE
= ListNode(val=None)
answer_root
= answer_root
answer
if (l1 is None) and (l2 is not None):
next = ListNode(l2.val)
answer.= l2.next
l2 elif (l1 is not None) and (l2 is None):
next = ListNode(l1.val)
answer.= l1.next
l1 elif (l1 is None) and (l2 is None):
return answer_root.next # remember to drop fake zero-node
# print(answer_root.next)
elif l1.val <= l2.val:
next = ListNode(l1.val)
answer.= l1.next
l1 elif l1.val > l2.val:
next = ListNode(l2.val)
answer.= l2.next
l2 else:
raise Exception
= answer.next
answer
print(answer_root)
print("l1:", l1)
print("l2:", l2)
4. Median of Two Sorted Arrays
Success
Runtime: 104 ms, faster than 28.31% of Python3 online submissions for Median of Two Sorted Arrays.
Memory Usage: 14.6 MB, less than 58.71% of Python3 online submissions for Median of Two Sorted Arrays.
median if n is is_odd = \(X_{i}\), i = n//2 + 1
median if n is even = \(\frac{X_i+X_j}{2}\), i = n/2, j=n/2+1
def next_or_none(itr):
try:
return next(itr)
except StopIteration:
return None
class Solution:
def findMedianSortedArrays(self, numsA: List[int], numsB: List[int]) -> float:
= len(numsA) + len(numsB)
n
= iter(numsA)
numsA = iter(numsB)
numsB
= bool(n % 2)
n_is_odd = not n_is_odd
n_is_even
if n_is_odd:
= n // 2
idx_1 = None
idx_2 else:
= n / 2 - 1
idx_1 = n / 2
idx_2
= next_or_none(numsA), next_or_none(numsB)
a, b
= -1
current_idx = None
current_value
# while True:
for _ in range(n):
+= 1
current_idx = current_value
prev_value
if (a is None) and (b is not None):
= b
current_value = next_or_none(numsB)
b elif (a is not None) and (b is None):
= a
current_value = next_or_none(numsA)
a elif a <= b:
= a
current_value = next_or_none(numsA)
a elif a > b:
= b
current_value = next_or_none(numsB)
b
if (current_idx == idx_1) and n_is_odd:
return current_value
if (current_idx == idx_2) and n_is_even:
return (prev_value + current_value) / 2
6. ZigZag Conversion
= [["-"] * 7] * 3
matrix
matrix
[['-', '-', '-', '-', '-', '-', '-'],
['-', '-', '-', '-', '-', '-', '-'],
['-', '-', '-', '-', '-', '-', '-']]
class Point:
def __init__(self):
self.x = 0
self.y = 0
def write(self, char):
self.y][self.x] = char
matrix[
def __repr__(self):
= matrix[self.y][self.x]
char return f"{[self.x, self.y]} -> {char}"
= Point()
p "x")
p.write( p
[0, 0] -> x
matrix
[['x', '-', '-', '-', '-', '-', '-'],
['x', '-', '-', '-', '-', '-', '-'],
['x', '-', '-', '-', '-', '-', '-']]
import numpy as np
numpy
matrix[]
print("\n".join(["".join(row) for row in matrix]))
-------
-------
-------