import heapq
class Solution:
def lastStoneWeight(self, stones: list[int]) -> int:
stones.append(0)
stones = list(map(lambda x: -x, stones))
heapq.heapify(stones)
while len(stones) > 1:
y, x = -heapq.heappop(stones), -heapq.heappop(stones)
if x != y:
heapq.heappush(stones, -(y - x))
return -heapq.heappop(stones)
844. Backspace String Compare
class Solution1:
def backspaceCompare(self, s: str, t: str) -> bool:
ss, st = [], []
for c in s:
if c != '#':
ss.append(c)
elif ss:
ss.pop()
for c in t:
if c != '#':
st.append(c)
elif st:
st.pop()
return ss == st
class Solution:
def backspaceCompare(self, s: str, t: str) -> bool:
ps, pt = len(s) - 1, len(t) - 1 # pointer
bs, bt = 0, 0 # backspace
def go_left(string, pointer, backspace):
while pointer >= 0 and (backspace or string[pointer] == '#'):
backspace += (-1) ** (string[pointer] != '#')
pointer -= 1
return pointer, backspace
while True:
(ps, bs), (pt, bt) = go_left(s, ps, bs), go_left(t, pt, bt)
if not (ps >= 0 and pt >= 0 and s[ps] == t[pt]):
return ps == pt == -1
ps -= 1
pt -= 1
299. Bulls and Cows
from collections import Counter
class Solution:
def getHint(self, s: str, g: str) -> str:
a, b = 0, 0
cs, cg = Counter(), Counter()
for i in range(len(s)):
if s[i] == g[i]:
a += 1
continue
if cg[s[i]]:
cg[s[i]] -= 1
b += 1
else:
cs[s[i]] += 1
if cs[g[i]]:
cs[g[i]] -= 1
b += 1
else:
cg[g[i]] += 1
return f'{a}A{b}B'
62. Unique Paths
import math
class Solution1:
def uniquePaths(self, m: int, n: int) -> int:
return math.comb((m - 1) + (n - 1), (n - 1))
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [1] + [0 for _ in range(n - 1)]
for _ in range(m):
for i in range(n - 1):
dp[i + 1] += dp[i]
return dp[n - 1]
424. Longest Repeating Character Replacement
class Solution:
# https://leetcode.com/problems/longest-repeating-character-replacement/solutions/278271
def characterReplacement(self, s: str, k: int) -> int:
c, mf = {}, 0 # counter, max_freq
l, N = 0, len(s)
for r in range(N):
c[s[r]] = c.get(s[r], 0) + 1
mf = max(mf, c[s[r]])
if not ((r + 1) - l - mf <= k): # shift right
c[s[l]] -= 1
l += 1
# find next if same
return N - l # length
class Solution2:
# https://leetcode.com/problems/longest-repeating-character-replacement/solutions/278271
def characterReplacement(self, s: str, k: int) -> int:
result = 0
c, mf = {}, 0 # counter, max_freq
for r in range(len(s)):
c[s[r]] = c.get(s[r], 0) + 1
mf = max(mf, c[s[r]])
if result - mf >= k:
c[s[r - result]] -= 1
else:
result += 1 # update when more
return result
class SolutionBS: # TODO: review
# https://leetcode.com/problems/longest-repeating-character-replacement/solutions/2805777
def characterReplacement(self, s: str, k: int) -> int:
def too_long(length: int):
c, mf = {}, 0
l = 0
for r in range(len(s)):
c[s[r]] = c.get(s[r], 0) + 1
if r + 1 - l > length:
c[s[l]] -= 1
l += 1
mf = max(mf, c[s[r]])
if length - mf <= k:
return False
return True
l, r = 0, len(s)
while l < r:
m = (l + r) // 2
length = m + 1
l, r = (l, m) if too_long(length) else (m + 1, r)
return (l - 1) + 1
438. Find All Anagrams in a String
from collections import Counter
class Solution:
def findAnagrams(self, s: str, p: str) -> list[int]:
result, s, P = [], s + ' ', len(p)
cp, cs = Counter(p), Counter(s[:P])
for i in range(len(s) - P):
if cp == cs:
result.append(i)
cs.subtract(s[i])
cs.update(s[i + P])
return result
70. Climbing Stairs
class Solution:
def climbStairs(self, n: int) -> int:
a, b = 1, 1
for _ in range(n):
a, b = b, a + b
return a
509. Fibonacci Number
class Solution:
def fib(self, n: int) -> int:
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
746. Min Cost Climbing Stairs
class Solution:
def minCostClimbingStairs(self, cost: list[int]) -> int:
a = b = 0
for c in cost:
a, b = b, min(a, b) + c
return min(a, b)
223. Rectangle Area
class Solution:
def computeArea(
self,
ax1: int,
ay1: int,
ax2: int,
ay2: int,
bx1: int,
by1: int,
bx2: int,
by2: int,
) -> int:
(ax1, ax2), (ay1, ay2), (bx1, bx2), (by1, by2) = map(
sorted,
((ax1, ax2), (ay1, ay2), (bx1, bx2), (by1, by2)),
)
return sum(
(
(ax2 - ax1) * (ay2 - ay1),
(bx2 - bx1) * (by2 - by1),
-(
max(0, min(ax2, bx2) - max(ax1, bx1))
* max(0, min(ay2, by2) - max(ay1, by1))
),
)
)
374. Guess Number Higher or Lower
# The guess API is already defined for you.
# @param num, your guess
# @return -1 if num is higher than the picked number
# 1 if num is lower than the picked number
# otherwise return 0
def guess(num: int) -> int:
...
class Solution:
def guessNumber(self, n: int) -> int:
l, r = 0, n
while l < r:
m = (l + r) // 2
if not guess(m):
return m
l, r = (l, m) if guess(m) < 0 else (m + 1, r)
return l
200. Number of Islands
class Solution:
def numIslands(self, grid) -> int:
M, N = len(grid), len(grid[0])
def dfs(m, n):
r = 0 <= m < M and 0 <= n < N and grid[m][n] == '1'
if r:
grid[m][n] = None
list(map(dfs, (m + 1, m - 1, m, m), (n, n, n + 1, n - 1)))
return r
return sum(dfs(m, n) for m in range(M) for n in range(N))
235. Lowest Common Ancestor of a Binary Search Tree
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root, p, q):
if root.val > max(p.val, q.val):
return self.lowestCommonAncestor(root.left, p, q)
if root.val < min(p.val, q.val):
return self.lowestCommonAncestor(root.right, p, q)
return root
733. Flood Fill
class Solution:
def floodFill(
self, image: list[list[int]], sr: int, sc: int, color: int
) -> list[list[int]]:
COLOR, M, N = image[sr][sc], len(image), len(image[0])
def dfs(m, n):
if not all([0 <= m < M, 0 <= n < N]):
return
if not all([image[m][n] == COLOR, image[m][n] != color]):
return
image[m][n] = color
list(map(dfs, (m + 1, m - 1, m, m), (n, n, n + 1, n - 1)))
dfs(sr, sc)
return image
26. Remove Duplicates from Sorted Array
class Solution1:
def removeDuplicates(self, nums: list[int]) -> int:
v, p = -101, 0 # ng
for i in range(len(nums)):
if nums[i] > v:
v = nums[p] = nums[i]
p += 1
return p
class Solution:
def removeDuplicates(self, nums: list[int]) -> int:
p = 1
for i in range(1, len(nums)):
if nums[p - 1] < nums[i]:
nums[p], p = nums[i], p + 1
return p
98. Validate Binary Search Tree
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isValidBST(self, root, lo=float('-inf'), hi=float('inf')) -> bool:
'''
[5,4,6,null,null,3,7] => false
'''
return (not root) or all(
[
lo < root.val < hi,
self.isValidBST(root.left, lo, root.val),
self.isValidBST(root.right, root.val, hi),
]
)
102. Binary Tree Level Order Traversal
from functools import reduce
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root) -> list[list[int]]:
result, q = [], [root]
while True:
q = [x for x in q if x]
v = [x.val for x in q]
if not v:
break
result.append(v)
q = reduce(lambda a, b: a + [b.left, b.right], q, [])
return result
704. Binary Search
class Solution:
def search(self, nums: list[int], target: int) -> int:
l, r = 0, len(nums)
while l < r:
m = (l + r) // 2
if nums[m] == target:
return m
l, r = (l, m) if nums[m] > target else (m + 1, r)
return -1
121. Best Time to Buy and Sell Stock
class Solution:
def maxProfit(self, prices) -> int:
l, r = prices[0], 0
for p in prices:
l, r = min(l, p), max(r, p - l)
return r
142. Linked List Cycle II
class Solution:
def detectCycle(self, head):
'''
.___a___.___C-b___.
(_________) -> C: cycle
b
slow: a+C-b + xC
fast: a+C-b + yC
2 slow = fast
=> a+C-b = (y-2x)C
=> a = (y-2x-1)C+b
.___(y-2x-1)C+b___.___C-b___.
(_________)
b
=> a mod C = b mod C
'''
l = r = head
while r and r.next:
l, r = l.next, r.next.next
if l is r:
break
else:
return
while head is not r:
head, r = head.next, r.next
return head
409. Longest Palindrome
class Solution:
def longestPalindrome(self, s: str) -> int:
r, pool = 0, set()
for c in s:
if c in pool:
pool.remove(c)
r += 1
else:
pool.add(c)
return r * 2 + bool(pool)
589. N-ary Tree Preorder Traversal
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def preorder(self, root):
return (
(root.val,) + sum((self.preorder(x) for x in root.children), ())
if root
else ()
)