LeetCode刷题笔记 - 常用的Python代码
We assume python 3.11, which is the python version used in LeetCode (see doc)
Common Data Structures
List
lst = [2,4,6]
lst.append(x)        # Add at end
lst.pop()            # Remove from end
lst.pop(i)           # Remove at index
lst.insert(i, x)     # Insert at index. 
                     # For lst=[y, z], lst.insert(1, x) results in [y, x, z]
lst.remove(x)        # Remove first occurrence
lst.sort()           # In-place sort
lst.reverse()        # In-place reverse
sorted(lst)          # Returns new sorted list
lst.index(x)         # Find first index of x
Tuple
Immutable, and hashable (can be used as element in set / key in dict)
Set
s = set([2,2,2,4,6])  # the same as `s = {2, 4, 6}`
s.add(x)              # Add to set, dedup
s.remove(x)           # Remove elem, if not exists throw err
s.discard(x)          # Remove elem, if not exists ignore
s.pop()               # Randomly pop one elem
s.union(t)
s.intersection(t)
s.difference(t)
s.symmetric_difference(t)
Dictionary
d.get(k, default)
d.keys(), d.values(), d.items()
d.pop(k)
d.popitem()
d.setdefault(k, default)
Deque: collections.deque
Double-ended queue.
from collections import deque
dq = deque([2,4,6])
dq.append(x)
dq.appendleft(x)
dq.pop()
dq.popleft()
dq.rotate(n)
Heap: heapq
heapq provides min-heap. A min-heap is a complete binary tree where every parent node <= its children.
Time complexity of useful ops:
access min elem:
O(1)insert / remove elem:
O(log N)create heap:
O(N)
Min-heap can be used to efficiently implement priority queue where tasks of highest priority is processed first.
nums = [(5, "task A"), (3, "task B"), (8, "task C"), (1, "task D")]
# nums is ordered after heapify
heapq.heapify(nums)
# nums is [(1, 'task D'), (3, 'task B'), (8, 'task C'), (5, 'task A')]
heapq.heappush(nums, (2, "task E"))
# nums is [(1, 'task D'), (2, 'task E'), (3, 'task B'), (8, 'task C'), (5, 'task A')]
# Peak smallest
smallest = nums[0]
# Pop smallest, re-heapify
# Elements are swapped in place to simulate ops on binary tree, so that heappop is O(log N)
smallest = heapq.heappop(nums)    # (1, 'task D')
Note: Conceptually, heap is a tree. In practice, we represent it as a sorted list. For each element at index
i,
- it’s left child is at
 2*i + 1- it’s right child is at
 2*i + 2- it’s parent is at
 (i - 1) // 2
Counter collections.Counter
Counter w/ efficient top-k most common retrieval (heap-based impl).
from collections import Counter
lst = [1,1,2,3,3,3,3,4,4,5]
c = Counter(lst)
# c.most_common(k) returns top k most common elements
# in the form [(elem, freq)]
c.most_common(2)    # [(3, 4), (1, 2)]
c.most_common(3)    # [(3, 4), (1, 2), (4, 2)]
# Iterator
c.elements()
# <itertools.chain object at 0x7fe91b2f2a70>
# Update
c.update([1,1,1,1,1,1])
c.most_common(2)    # [(1, 8), (3, 4)]
Dictionary w/ Default Value: collections.defaultdict
Just a “nice to have”, not really a substantially different data structure.
Instead of
d = dict()
# ...
if key not in d:
  d[key] = []
d[key].append(10)
we can use defaultdict and write
from collections import defaultdict
# defaultdict(default_factory)
# e.g. defaultdict(lamdba: "foobar")
d = defaultdict(list)
# ...
d[key].append(10)
Note that an item is created when you call
d[key]
If you don’t want it to be created, you can just call d.get(key).
Common Code Snippets
Heap with custom comparator
class Task
    def __init__(self, name, prio):
      self.name = name
      # Smaller means higher priority
      self.prio = prio
    def __lt__(self, other):
      return self.prio < other.prio
import heapq
heap = []
heapq.heappush(heap, Task("Do laundry", 2))
heapq.heappush(heap, Task("Write code", 1))
print(heapq.heappop(heap).name)   # "Write code"