List Comprehension
1
2
3m, n = 10, 10
dp = [0]*n # 1d array
dp = [[False]*n for _ in range(m)] # 2d array, never use [[False]*n]*m, it is a trap! Because * is copying the address of the object (list)Binary Search
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import bisect
"""
https://docs.python.org/3/library/bisect.html
bisect.bisect_left returns the leftmost place in the sorted list to insert the given element.
bisect.bisect_right returns the rightmost place in the sorted list to insert the given element.
They are equivalent when the the element to be inserted is not present in the list. Hence, they are not equivalent when the element to be inserted is in the list.
"""
nums = [-1,1]
# The element does not present in nums
lIdx = bisect.bisect_left(nums, 0) # return 1
rIdx = bisect.bisect_right(nums, 0) # return 1
# The element presents in nums
lIdx = bisect.bisect_left(nums, 1) # return 1
rIdx = bisect.bisect_right(nums, 1) # return 2Doubly Ended Queue
1
2
3
4
5q = collections.dequeue([1,2,3]) # initialize a Queue, e.g., tree level order traverse
q.append() # append at end
q.appendleft() # append at head
q.pop() # pop q[-1]
q.popleft() # pop q[0]Priority Queue
1
2
3
4
5
6
7
8
9
10import heapq
"""
# https://docs.python.org/3/library/heapq.html
"""
h = []
heapq.heapify(h) # min-heap by default; mulitplying the input with "-1" to use as a max-heap
heapq.heappush(h, 5)
heapq.heappop(h)
heapq.nlargest(3, h)
heapq.nsmallest(3, h)- LeetCode 347. Top K Frequent Elements. Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order.
1
2
3
4
5
6
7
8
9def topKFrequent(self, nums: List[int], k: int) -> List[int]:
"""
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
"""
count = collections.Counter(nums)
# note the usage of "key" parameter in nlargest()
return heapq.nlargest(k, count.keys(), key=count.get)
- LeetCode 347. Top K Frequent Elements. Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order.
misc
nonlocal, the nonlocal keyword is used to work with variables inside nested functions, where the variable should not belong to the inner function. Use the keyword nonlocal to declare that the variable is not local, which is particularly useful when updating some global variables in recursive calls.
- LeetCode 124. Binary Tree Maximum Path Sum. A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence at most once. Note that the path does not need to pass through the root. The path sum of a path is the sum of the node’s values in the path. Given the root of a binary tree, return the maximum path sum of any non-empty path.
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# 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 maxPathSum(self, root: Optional[TreeNode]) -> int:
max_sum = float('-inf')
def dfs(node):
if not node:
return 0
nonlocal max_sum
# Recursively find the maximum sum in the left and right subtrees
left_sum = max(dfs(node.left), 0)
right_sum = max(dfs(node.right), 0)
# Update the current maximum path sum
current_sum = left_sum + node.val + right_sum
max_sum = max(max_sum, current_sum)
# Return the maximum sum that includes either the left or right subtree
return max(left_sum, right_sum) + node.val
dfs(root)
return max_sum
- LeetCode 124. Binary Tree Maximum Path Sum. A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence at most once. Note that the path does not need to pass through the root. The path sum of a path is the sum of the node’s values in the path. Given the root of a binary tree, return the maximum path sum of any non-empty path.
chr() vs. ord(); ord() function returns an integer representing the Unicode character; chr() function returns the Unicode character with an integer as input
- LeetCode 49. Group Anagrams. Given an array of strings strs, group the anagrams together. You can return the answer in any order. An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
1
2
3
4
5
6
7
8
9
10
11
12
13
14def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
"""
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
"""
tmpMap = collections.defaultdict(list)
for s in strs:
tmp = [0]*26
for char in s:
# ord('a') returns the integer representation of 'a'
tmp[ord(char)-ord('a')] += 1
tmpMap[tuple(tmp)].append(s)
#print(tuple(tmp))
return [val for val in tmpMap.values()]
- LeetCode 49. Group Anagrams. Given an array of strings strs, group the anagrams together. You can return the answer in any order. An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
sort() and sorted()
1
2
3
4
5
6
7
8nums = [[23,1],[4,56]]
nums.sort(key=lambda x:x[0]) # [[4, 56], [23, 1]], non-descending by default
nums.sort(key=lambda x:x[0], reverse=True) # [[23, 1], [4, 56]], non-ascending using "reverse"
nums.sort(key=lambda x:x[1]) # [[23, 1], [4, 56]]
nums.sort(key=lambda x:x[1], reverse=True) # [[4, 56], [23, 1]]
newArray = sorted(nums,key=lambda x:x[0],reverse=True) # a deep copy of numsfilter(), map() and reduce()[1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from functools import reduce
numbers = range(10)
# Use map(), filter(), and reduce() to preprocess and aggregate the list of numbers
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(even_numbers) # <filter object at 0x7ff6d0eceda0>, note that filter() returns an iterable object
print(list(even_numbers)) # [0, 2, 4, 6, 8]
squares = map(lambda x: x**2, numbers)
print(squares) # <map object at 0x7ff6d103e950>
sum_of_squares = reduce(lambda x, y: x + y, squares)
print(sum_of_squares) # 285any() and all() are built-in functions that allow for checking if any or all elements in an iterable meet a certain condition.
1
2
3data = [1, 3, 5, 7]
print(any(x % 2 == 0 for x in data)) # False
print(all(x % 2 == 1 for x in data)) # True*args and **kwargs
Need to fill in examplesassert(), raise()
1
2
3
4
5
6
7
8
9
10
11
12a = 1
assert a>100 # False
if a > 100:
raise Exception('a cannot be higher than 100') # raise standard exception
class ScoreException(Exception):
def __init__(self):
super().__init__('score cannot be higher than 100')
if score > 100:
raise ScoreException() # raise customized exceptionf-string[2]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# lambda functions
from datetime import date
print(f"Today is {date.today()}") # Today is 2023-03-13
print(f"This is result from a lambda: {(lambda x: x ** 2)(3)}") # This is result from a lambda: 9
# percentage formatting: {:.n%}
jumbo_shrimp = 0.4245
print(f"42% of something: {jumbo_shrimp:.0%}") # 42% of something: 42%
print(f"Percentage of something: {jumbo_shrimp:.1%}") # Percentage of something: 42.4%
print(f"Percentage of another thing: {jumbo_shrimp:.2%}") # Percentage of another thing: 42.45%
# printing the value of a variable: {=}
sassy = 1
pants = 0
print(f"{sassy=}") # sassy=1
print(f"{pants = }") # pants = 0
Classes
- init(), str() and gt()[3]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Panda():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f'Panda(name="{self.name}", age={self.age})'
def __gt__(self, otherPanda):
return self.age > otherPanda.age
p1, p2 = Panda("Yuanyuan", 1), Panda("Huanhuan", 2)
print(p1) # Panda(name='Yuanyuan',age=1), which calls the __str__() function
print(p1>p2) # False, it compares 2 objects by the __gt__() function
- init(), str() and gt()[3]
principals
- Docstrings[4], the first line of the docstring is a brief explanation of the function’s purpose. The next element of a docstring is an explanation of the function’s arguments.
1
2
3def population_density(population, land_area):
"""Calculate the population density of an area."""
return population / land_area
- Docstrings[4], the first line of the docstring is a brief explanation of the function’s purpose. The next element of a docstring is an explanation of the function’s arguments.