0% found this document useful (0 votes)
5 views37 pages

Python Data Structures For Leetcode

The document discusses the importance of various Python data structures in solving LeetCode problems, emphasizing that the right data structure can significantly improve the efficiency of solutions. It covers lists, tuples, strings, sets, frozensets, dictionaries, defaultdicts, counters, and deques, detailing their characteristics, time complexities, common use cases, and potential mistakes. The document serves as a guide for leveraging these structures effectively in coding challenges.

Uploaded by

mayankekbote12
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views37 pages

Python Data Structures For Leetcode

The document discusses the importance of various Python data structures in solving LeetCode problems, emphasizing that the right data structure can significantly improve the efficiency of solutions. It covers lists, tuples, strings, sets, frozensets, dictionaries, defaultdicts, counters, and deques, detailing their characteristics, time complexities, common use cases, and potential mistakes. The document serves as a guide for leveraging these structures effectively in coding challenges.

Uploaded by

mayankekbote12
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

1.

Why Python data structures matter in LeetCode

In LeetCode, many problems are solved not by complicated syntax, but by selecting the
correct data structure.

For example:

• a brute-force solution may be O(n²)

• using a set can reduce lookup to O(1)

• using a dict can reduce repeated searches

• using a deque can make queue operations efficient

• using heapq helps when repeated minimum or maximum access is needed

• using Counter simplifies frequency counting

In Python, especially, good use of built-in data structures often makes solutions much
shorter, cleaner, and faster.

2. LIST

What is a list?

A Python list is a dynamic array-like data structure. It can store elements of different types,
though in LeetCode we usually store same-type elements.

nums = [1, 2, 3, 4]

Why list is extremely important in LeetCode

Most LeetCode inputs in Python are given as lists:

• List[int]

• List[str]

• List[List[int]]

Lists are used for:

• arrays

• stacks

• dynamic result storage

• matrix representation

• graph adjacency lists

• backtracking paths

Time complexity

• Access by index: O(1)


• Update by index: O(1)

• Append at end: O(1) amortized

• Pop at end: O(1)

• Insert at beginning/middle: O(n)

• Pop from beginning: O(n)

• Search: O(n)

Important methods

• append(x)

• extend(iterable)

• insert(i, x)

• pop()

• pop(i)

• remove(x)

• index(x)

• count(x)

• sort()

• reverse()

• copy()

Example

nums = [10, 20, 30]


print(nums[1]) # 20

nums[1] = 50
print(nums) # [10, 50, 30]

[Link](70)
print(nums) # [10, 50, 30, 70]

[Link]()
print(nums) # [10, 50, 30]

Common LeetCode use cases

a) Traversal

for x in nums:
print(x)

b) Index-based loop
for i in range(len(nums)):
print(i, nums[i])

c) Backtracking path

path = []
[Link](1)
[Link](2)
[Link]()

d) Matrix

grid = [
[1, 2],
[3, 4]
]
print(grid[1][0]) # 3

Common mistakes

Mistake 1: using pop(0) repeatedly

q = [1, 2, 3]
[Link](0) # O(n)

This is slow for queue behavior. Use [Link] instead.

Mistake 2: shallow copy in nested lists

grid = [[0] * 3] * 4

All rows refer to the same list.

Wrong behavior:

grid[0][0] = 1
print(grid)
# [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]

Correct:

grid = [[0] * 3 for _ in range(4)]

3. TUPLE

What is a tuple?

A tuple is an immutable ordered collection.

point = (2, 3)

Why tuple matters in LeetCode

Tuples are useful when:

• you want fixed grouped values


• you need hashable composite keys in set or dict

• you want to store coordinates like (r, c)

• you push structured items into heaps

Time complexity

• Access by index: O(1)

• Search: O(n)

• Cannot modify after creation

Example

p = (10, 20)
print(p[0]) # 10

Important use cases

a) coordinate storage

visited = set()
[Link]((2, 3))

b) heap elements

import heapq

heap = []
[Link](heap, (2, "taskA"))
[Link](heap, (1, "taskB"))
print([Link](heap)) # (1, 'taskB')

c) returning multiple values

def get_pair():
return (4, 5)

Common mistake

Trying to modify tuple:

t = (1, 2)
# t[0] = 10 # error

4. STRING

What is a string?

A string is an immutable sequence of characters.

s = "hello"

Why string handling matters in LeetCode


Very common in:

• palindrome problems

• substring problems

• anagrams

• parsing

• sliding window

• stack-based decoding

• string building

Time complexity

• Access by index: O(1)

• Slice: usually O(k)

• Concatenation repeatedly in loop can be inefficient

Important operations

• len(s)

• s[i]

• s[start:end]

• [Link]()

• [Link]()

• [Link]()

• [Link]()

• ''.join(list_of_strings)

• [Link](sub)

• [Link](ch)

Example

s = "hello"
print(s[1]) #e
print(s[:4]) # hell
print(s[::-1]) # olleh

Important note: strings are immutable

Wrong:

s[0] = 'H'

Correct ways:
s = 'H' + s[1:]

or

chars = list(s)
chars[0] = 'H'
s = ''.join(chars)

Efficient string building

Bad:

ans = ""
for ch in ['a', 'b', 'c']:
ans += ch

Better:

chars = []
for ch in ['a', 'b', 'c']:
[Link](ch)
ans = ''.join(chars)

5. SET

What is a set?

A set stores unique elements using hashing.

seen = {1, 2, 3}

or

seen = set()

Why set is important in LeetCode

Set is one of the most frequently used Python data structures for:

• duplicate checking

• membership testing

• visited tracking

• removing duplicates logically

• sliding window uniqueness

Time complexity

Average case:

• Add: O(1)

• Remove: O(1)
• Contains: O(1)

Important methods

• add(x)

• remove(x) → error if absent

• discard(x) → no error if absent

• pop()

• clear()

• union()

• intersection()

• difference()

Example

s = set()
[Link](10)
[Link](20)
[Link](10)

print(s) # {10, 20}


print(20 in s) # True

LeetCode examples

a) Contains Duplicate

def containsDuplicate(nums):
seen = set()
for x in nums:
if x in seen:
return True
[Link](x)
return False

b) Longest Consecutive Sequence

def longestConsecutive(nums):
num_set = set(nums)
best = 0

for x in num_set:
if x - 1 not in num_set:
length = 1
while x + length in num_set:
length += 1
best = max(best, length)
return best

Common mistakes

Mistake 1: adding unhashable types

s = set()
# [Link]([1, 2]) # error: list is unhashable

Use tuple instead:

[Link]((1, 2))

Mistake 2: using remove() when key may not exist

[Link](10) # can raise KeyError

Safer:

[Link](10)

6. FROZENSET

What is frozenset?

An immutable version of set.

fs = frozenset([1, 2, 3])

Why it matters

Less common, but useful when:

• you need a set-like object as a key in another set/dict

• representing immutable groups

Example

a = frozenset([1, 2])
b = frozenset([2, 3])

s = {a, b}
print(s)

LeetCode relevance

Rare, but sometimes useful in state compression or memoization where the state is an
unordered group.
7. DICT

What is a dict?

A dict stores key-value pairs using hashing.

mp = {"a": 1, "b": 2}

Why dict is extremely important in LeetCode

Probably the single most useful Python structure after list.

Used for:

• frequency counting

• index lookup

• grouping

• adjacency lists

• memoization

• prefix sum tracking

• dynamic mapping

Time complexity

Average case:

• Insert/update: O(1)

• Access: O(1)

• Delete: O(1)

• Membership in keys: O(1)

Important methods

• d[key] = value

• [Link](key, default)

• [Link](key, default)

• [Link]()

• [Link]()

• [Link]()

• key in d

Example

mp = {}
mp[1] = 100
mp[2] = 200
print(mp[1]) # 100
print([Link](3, 0)) # 0

Important LeetCode patterns

a) value to index map

def twoSum(nums, target):


mp = {}

for i, x in enumerate(nums):
need = target - x
if need in mp:
return [mp[need], i]
mp[x] = i

b) frequency map

freq = {}
for x in nums:
freq[x] = [Link](x, 0) + 1

c) character count

count = {}
for ch in s:
count[ch] = [Link](ch, 0) + 1

d) grouping

groups = {}
for word in strs:
key = ''.join(sorted(word))
if key not in groups:
groups[key] = []
groups[key].append(word)

Iterating over dict

keys

for key in mp:


print(key, mp[key])

items

for key, value in [Link]():


print(key, value)

Common mistakes

Mistake 1: direct access without checking

freq[x] += 1
This fails if x not present.

Use:

freq[x] = [Link](x, 0) + 1

Mistake 2: confusing in dict

if x in mp:

This checks keys, not values.

8. DEFAULTDICT

What is defaultdict?

A special dictionary from collections that provides a default value automatically.

from collections import defaultdict

Syntax

d = defaultdict(int)

Here, missing keys default to 0.

Common types

• defaultdict(int) → default 0

• defaultdict(list) → default []

• defaultdict(set) → default set()

Why it is useful in LeetCode

It simplifies code for:

• counting

• grouping

• graph adjacency

• collections of lists/sets

Example 1: counting

from collections import defaultdict

freq = defaultdict(int)
for x in [1, 2, 2, 3]:
freq[x] += 1

print(freq) # defaultdict(<class 'int'>, {1: 1, 2: 2, 3: 1})

Example 2: grouping anagrams


from collections import defaultdict

groups = defaultdict(list)
for word in ["eat", "tea", "tan", "ate", "nat", "bat"]:
key = ''.join(sorted(word))
groups[key].append(word)

print(list([Link]()))

Example 3: graph adjacency list

from collections import defaultdict

graph = defaultdict(list)
edges = [(0, 1), (0, 2), (1, 3)]

for u, v in edges:
graph[u].append(v)

print(graph[0]) # [1, 2]

Common mistake

A defaultdict creates missing keys when accessed.

d = defaultdict(int)
print(d[10]) # creates key 10 with value 0

Sometimes this is okay, sometimes it changes dictionary size unexpectedly.

9. COUNTER

What is Counter?

Counter is a special dictionary for frequency counting.

from collections import Counter

Why Counter is useful

It makes frequency-based LeetCode problems much simpler.

Example

from collections import Counter

freq = Counter([1, 2, 2, 3, 3, 3])


print(freq) # Counter({3: 3, 2: 2, 1: 1})

Useful methods

• Counter(iterable)
• freq[x]

• most_common(k)

• arithmetic-like operations on counters

Example 1: Valid Anagram

from collections import Counter

def isAnagram(s, t):


return Counter(s) == Counter(t)

Example 2: Top K frequent

from collections import Counter

freq = Counter(nums)
print(freq.most_common(2))

Example 3: direct frequency access

freq = Counter("banana")
print(freq['a']) # 3

When to use Counter

Use it when:

• problem is mainly counting

• readability matters

• you want concise code

When not to use Counter

Sometimes manual dict counting is better if:

• you need custom behavior

• performance tuning matters deeply

• interviewer expects explicit logic

10. DEQUE

What is deque?

deque stands for double-ended queue. It comes from collections.

from collections import deque

It supports efficient insertion and removal from both ends.

Why deque is extremely important in LeetCode


It is used for:

• queue operations

• BFS

• sliding window maximum

• monotonic queue

• stack-like operations

• palindrome style two-end processing

Time complexity

• append(): O(1)

• appendleft(): O(1)

• pop(): O(1)

• popleft(): O(1)

Important methods

• append(x)

• appendleft(x)

• pop()

• popleft()

• peek is done by indexing like dq[0] or dq[-1]

Example

from collections import deque

dq = deque()
[Link](10)
[Link](20)
[Link](5)

print(dq) # deque([5, 10, 20])


print([Link]()) # 5
print([Link]()) # 20

Queue usage

from collections import deque

q = deque()
[Link](1)
[Link](2)
print([Link]()) # 1
Stack usage

st = deque()
[Link](10)
[Link](20)
print([Link]()) # 20

BFS example

from collections import deque

def bfs(graph, start):


q = deque([start])
visited = {start}

while q:
node = [Link]()
print(node)

for nei in graph[node]:


if nei not in visited:
[Link](nei)
[Link](nei)

Sliding window maximum pattern

from collections import deque

def maxSlidingWindow(nums, k):


dq = deque()
ans = []

for i, x in enumerate(nums):
while dq and dq[0] <= i - k:
[Link]()

while dq and nums[dq[-1]] < x:


[Link]()

[Link](i)

if i >= k - 1:
[Link](nums[dq[0]])

return ans
Common mistake

Using list as queue:

q = []
[Link](1)
[Link](0) # slow

Use deque:

q = deque()
[Link](1)
[Link]()

11. STACK IN PYTHON

Is there a separate stack type?

Python does not have a special built-in Stack class for most LeetCode work. Usually we use:

• list as stack

• sometimes deque as stack

Best practice

For most stack problems, use list.

stack = []
[Link](10) # push
[Link](20)
print([Link]()) # 20

Time complexity

• push (append): O(1)

• pop from end: O(1)

• peek: stack[-1] is O(1)

Example: Valid Parentheses

def isValid(s):
stack = []
pairs = {')': '(', ']': '[', '}': '{'}

for ch in s:
if ch in '([{':
[Link](ch)
else:
if not stack or stack[-1] != pairs[ch]:
return False
[Link]()
return not stack

Common stack problems

• Valid Parentheses

• Next Greater Element

• Daily Temperatures

• Decode String

• Largest Rectangle in Histogram

• Remove K Digits

• Monotonic stack problems

list vs deque for stack

Usually:

• list is perfectly fine for stack

• deque also works

• list is simpler and very common

12. QUEUE IN PYTHON

What should be used as queue?

For queue in Python, use [Link].

Why not use list?

Because removing from front is slow:

• [Link](0) is O(n)

With deque:

• popleft() is O(1)

Example

from collections import deque

q = deque()
[Link](10)
[Link](20)
print([Link]()) # 10

LeetCode use cases

• BFS in trees
• BFS in graphs

• shortest path in unweighted graph

• rotting oranges

• level order traversal

• topological sort

Example: binary tree level order

from collections import deque

def levelOrder(root):
if not root:
return []

q = deque([root])
result = []

while q:
level = []
for _ in range(len(q)):
node = [Link]()
[Link]([Link])

if [Link]:
[Link]([Link])
if [Link]:
[Link]([Link])

[Link](level)

return result

13. HEAPQ

What is heapq?

Python’s heapq module implements a min-heap.

import heapq

Why it is important in LeetCode

Used for:

• Kth smallest/largest

• top k elements
• scheduling

• merge k sorted lists

• Dijkstra

• greedy problems

• median-like processing

Time complexity

• push: O(log n)

• pop: O(log n)

• peek smallest: O(1) via heap[0]

Important methods

• [Link](heap, x)

• [Link](heap)

• [Link](lst)

• [Link](heap, x)

• [Link](k, iterable)

• [Link](k, iterable)

Example

import heapq

heap = []
[Link](heap, 5)
[Link](heap, 1)
[Link](heap, 3)

print(heap[0]) #1
print([Link](heap)) # 1
print([Link](heap)) # 3

Heapify example

import heapq

nums = [4, 1, 7, 2]
[Link](nums)
print(nums[0]) # smallest element

Max heap in Python

Python heapq is min-heap by default. To simulate max-heap, store negative values.


import heapq

heap = []
for x in [5, 1, 10]:
[Link](heap, -x)

print(-[Link](heap)) # 10

Example: Kth largest

import heapq

def findKthLargest(nums, k):


heap = []

for x in nums:
[Link](heap, x)
if len(heap) > k:
[Link](heap)

return heap[0]

Heap of tuples

import heapq

heap = []
[Link](heap, (2, "taskB"))
[Link](heap, (1, "taskA"))
print([Link](heap)) # (1, 'taskA')

Python compares tuple elements lexicographically.

Common mistakes

Mistake 1: expecting full sorted order

A heap is not a fully sorted list. Only heap[0] is guaranteed smallest.

Mistake 2: trying max-heap directly

Need negation or custom pattern.

14. BISECT

What is bisect?

The bisect module helps with binary search in sorted lists.

import bisect

Why useful in LeetCode


Used when:

• data is sorted

• you need insertion position

• you need lower bound / upper bound

• solving binary-search-like ordered problems

Important functions

• bisect.bisect_left(arr, x)

• bisect.bisect_right(arr, x)

• [Link](arr, x)

Example

import bisect

arr = [1, 2, 4, 4, 5]

print(bisect.bisect_left(arr, 4)) # 2
print(bisect.bisect_right(arr, 4)) # 4

Meaning

• bisect_left: first valid insertion index

• bisect_right: insertion index after all equal elements

Example: search insert position

import bisect

def searchInsert(nums, target):


return bisect.bisect_left(nums, target)

Example: maintain sorted list

import bisect

arr = [1, 3, 5]
[Link](arr, 4)
print(arr) # [1, 3, 4, 5]

Important limitation

Insertion into list is still O(n) because elements must shift.

So bisect gives fast searching, not always fast insertion overall.

15. SORTED LIST PATTERN IN PYTHON


Python standard library does not provide a full balanced BST like Java’s TreeSet or TreeMap.

This is important.

So what do Python LeetCode solutions do?

Usually one of these:

• use a sorted list + bisect

• use heapq when only min/max needed

• use a set/dict if ordering not needed

• in rare cases, use third-party sortedcontainers locally, but not in LeetCode unless
allowed

• redesign logic to avoid needing a tree structure

If sorted dynamic order is needed

Example:

• maintain sorted list

• use bisect_left / bisect_right

But insertion/deletion in middle remains O(n).

This is why some Java TreeSet solutions do not translate directly to Python as efficiently.

16. COUNTER + HEAPQ COMBINATION

This is a very important LeetCode combination.

Example: Top K Frequent Elements

from collections import Counter


import heapq

def topKFrequent(nums, k):


freq = Counter(nums)
heap = []

for num, count in [Link]():


[Link](heap, (count, num))
if len(heap) > k:
[Link](heap)

return [num for count, num in heap]

This combination appears in many problems.


17. DICT + LIST COMBINATION

Another common pattern.

Example: Group Anagrams

from collections import defaultdict

def groupAnagrams(strs):
groups = defaultdict(list)

for word in strs:


key = ''.join(sorted(word))
groups[key].append(word)

return list([Link]())

Example: graph adjacency

from collections import defaultdict

graph = defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u)

18. SET + QUEUE COMBINATION

Used heavily in BFS and graph traversal.

Example

from collections import deque

def bfs(graph, start):


q = deque([start])
visited = {start}

while q:
node = [Link]()

for nei in graph[node]:


if nei not in visited:
[Link](nei)
[Link](nei)

Why both?

• queue controls processing order

• visited set prevents repeated processing


19. LIST AS MATRIX

A matrix in Python is usually represented as a list of lists.

grid = [
[1, 2, 3],
[4, 5, 6]
]

Access

print(grid[1][2]) # 6

Traversal

rows = len(grid)
cols = len(grid[0])

for r in range(rows):
for c in range(cols):
print(grid[r][c])

Common LeetCode use cases

• number of islands

• flood fill

• matrix traversal

• DP tables

• shortest path in grid

• spiral matrix

Important matrix initialization

Correct

dp = [[0] * m for _ in range(n)]

Wrong

dp = [[0] * m] * n

20. GRAPH REPRESENTATION

Graphs in Python are often represented using:

• dict of lists

• defaultdict(list)

• list of lists if node count fixed and nodes are 0 to n-1


Example: adjacency list with fixed nodes

n=5
graph = [[] for _ in range(n)]

edges = [(0, 1), (0, 2), (1, 3)]


for u, v in edges:
graph[u].append(v)

Example: defaultdict

from collections import defaultdict

graph = defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u)

When to use what?

Use list of lists when:

• nodes are integer indexed

• node count known

• faster and simple

Use defaultdict(list) when:

• labels may be arbitrary

• graph sparse and flexible

• dynamic building easier

21. CUSTOM OBJECTS

Python allows custom classes, but in LeetCode most solutions use tuples, dicts, and lists more
often.

Still, custom objects matter sometimes.

Example

class NodeState:
def __init__(self, node, dist):
[Link] = node
[Link] = dist

Hashability issue

If you want to put custom objects into sets or dict keys, you need proper hashing/equality
behavior.
Usually easier:

• use tuples instead of custom objects

Example:

visited = set()
[Link]((row, col))

instead of custom class coordinates.

For heaps

Tuples are again usually easier:

[Link](heap, (dist, node))

22. COMMON LEETCODE DATA STRUCTURE PATTERNS IN PYTHON

Now let us map problem patterns to Python data structures.

Pattern 1: set for duplicate detection

Problem type

Need to know whether something has already appeared.

Example

def containsDuplicate(nums):
seen = set()
for x in nums:
if x in seen:
return True
[Link](x)
return False

Pattern 2: dict for frequency counting

Problem type

Need count of occurrences.

Example

def count_freq(nums):
freq = {}
for x in nums:
freq[x] = [Link](x, 0) + 1
return freq

Or:
from collections import Counter
freq = Counter(nums)

Pattern 3: dict for index lookup

Problem type

Need previous occurrence quickly.

Example

def twoSum(nums, target):


mp = {}
for i, x in enumerate(nums):
need = target - x
if need in mp:
return [mp[need], i]
mp[x] = i

Pattern 4: list as stack

Problem type

Matching symbols or nearest greater/smaller.

Example

def isValid(s):
st = []
pairs = {')': '(', ']': '[', '}': '{'}

for ch in s:
if ch in '([{':
[Link](ch)
else:
if not st or st[-1] != pairs[ch]:
return False
[Link]()
return not st

Pattern 5: deque as queue for BFS

Problem type

Level order, shortest path in unweighted graph, traversal.

Example
from collections import deque

def bfs(graph, start):


q = deque([start])
seen = {start}

while q:
node = [Link]()
for nei in graph[node]:
if nei not in seen:
[Link](nei)
[Link](nei)

Pattern 6: deque as monotonic queue

Problem type

Sliding window maximum/minimum.

Already shown above.

Pattern 7: heapq for top-k or repeated min extraction

Example

import heapq

def kthSmallest(nums, k):


[Link](nums)
for _ in range(k - 1):
[Link](nums)
return [Link](nums)

Pattern 8: tuple as composite key

Problem type

Need coordinate/state identity.

Example

visited = set()
[Link]((r, c, mask))
23. WHEN TO USE WHAT

This is one of the most important sections.

Use list when:

• you need dynamic array behavior

• random index access matters

• building answers

• using stack

• storing graph adjacency lists

Use tuple when:

• data should not change

• composite key needed in set/dict

• heap elements need multiple fields

• coordinates/states

Use set when:

• uniqueness matters

• fast membership test needed

• duplicate detection

• visited tracking

Use dict when:

• key-value mapping needed

• frequency counts

• lookup of previous positions

• grouping

• adjacency mapping

Use defaultdict when:

• you repeatedly initialize missing keys

• grouping into lists/sets

• adjacency lists

• counting

Use Counter when:

• frequency counting is the main task


• concise code helps

Use deque when:

• queue needed

• BFS

• popleft required

• sliding window maximum

• double-ended operations needed

Use heapq when:

• repeated smallest element needed

• top-k logic

• scheduling

• greedy extraction

• Dijkstra

Use bisect when:

• sorted list is given or maintained

• you need insertion/search position

• binary search boundary logic

24. IMPORTANT DIFFERENCES

list vs deque

list

• good for stack

• good for random access

• bad for queue front removal

deque

• excellent for queue

• excellent for both-end operations

• not ideal for frequent random indexing

Use:

• list for stack

• deque for queue/BFS/sliding window


dict vs defaultdict

dict

• explicit control

• missing key raises KeyError

defaultdict

• simpler for grouped/default behavior

• auto-creates missing entries

Use:

• dict when you want full control

• defaultdict when missing-key initialization is repetitive

dict counting vs Counter

dict

• explicit and flexible

Counter

• concise and powerful for pure counting

Use:

• Counter for frequency-heavy problems

• dict if custom logic needed

set vs dict

set

• stores only keys / unique values

dict

• stores key-value associations

Use:

• set when only existence matters

• dict when additional info must be stored


heapq vs sorting

sorting

• good if you need full sorted order once

heapq

• good when repeatedly extracting smallest/largest

• good for streaming/top-k problems

25. COMMON LEETCODE PROBLEMS MAPPED TO PYTHON DATA STRUCTURES

set

• Contains Duplicate

• Longest Consecutive Sequence

• Happy Number

• visited in graph/grid problems

dict

• Two Sum

• Isomorphic Strings

• Subarray Sum Equals K

• Copy List with Random Pointer

• LRU-cache-like logic conceptually

Counter

• Valid Anagram

• Top K Frequent Elements

• Find All Anagrams in a String

• Majority Element style counting

deque

• Binary Tree Level Order Traversal

• Rotting Oranges

• Sliding Window Maximum

• Word Ladder

• 0-1 BFS variants


list as stack

• Valid Parentheses

• Daily Temperatures

• Next Greater Element

• Decode String

• Largest Rectangle in Histogram

heapq

• Kth Largest Element

• Merge K Sorted Lists

• Meeting Rooms II

• Find Median from Data Stream

• Dijkstra

bisect

• Search Insert Position

• binary search boundary problems

• maintaining sorted lists

26. ITERATION PATTERNS YOU MUST KNOW

List

for x in nums:
print(x)

List with index

for i, x in enumerate(nums):
print(i, x)

Dict keys

for k in mp:
print(k, mp[k])

Dict items

for k, v in [Link]():
print(k, v)

Set

for x in seen:
print(x)
Matrix

for r in range(len(grid)):
for c in range(len(grid[0])):
print(grid[r][c])

27. MEMORY AND COPYING PITFALLS

This is very important in Python.

Simple list copy

Wrong if aliasing not intended

a = [1, 2, 3]
b=a
[Link](4)
print(a) # [1, 2, 3, 4]

Correct shallow copy

b = a[:]

or

b = list(a)

or

b = [Link]()

Nested lists

For nested structures, shallow copy may not be enough.

Example

a = [[1], [2]]
b = [Link]()
b[0].append(99)
print(a) # [[1, 99], [2]]

Need deep copy if full separation is required:

import copy
b = [Link](a)

Backtracking important rule

When storing a current path:

[Link](path[:])

not

[Link](path)
Because path changes later.

28. HASHABILITY RULES

Very important for set and dict keys.

Hashable

• int

• str

• tuple (if all contents hashable)

• frozenset

Not hashable

• list

• set

• dict

Wrong

visited = set()
# [Link]([1, 2]) # error

Correct

[Link]((1, 2))

29. COMMON PERFORMANCE ADVICE FOR PYTHON IN LEETCODE

1. Use set and dict for fast lookups.

2. Use deque for BFS and queue behavior.

3. Use list for stack.

4. Use heapq for top-k and repeated min extraction.

5. Use Counter or defaultdict(int) for frequencies.

6. Avoid pop(0) on list.

7. Avoid repeated string concatenation in loops for large strings.

8. Use tuples for visited states and coordinates.

9. Be careful with shallow copies.

10. Prefer built-in structures over overcomplicated custom classes unless truly needed
30. A VERY PRACTICAL CHOOSING GUIDE

Ask yourself these questions.

Do I need fast membership lookup?

Use set or dict

Do I need counts/frequencies?

Use Counter, dict, or defaultdict(int)

Do I need key-value mapping?

Use dict

Do I need uniqueness only?

Use set

Do I need FIFO processing?

Use deque

Do I need LIFO processing?

Use list as stack

Do I need repeated minimum/maximum extraction?

Use heapq

Do I need ordered search positions in a sorted sequence?

Use bisect

Do I need a composite state as a key?

Use tuple

Do I need to build a matrix or adjacency list?

Use nested list or defaultdict(list)

31. FINAL SUMMARY TABLE

list

Dynamic array, stack, matrix, backtracking path, adjacency list

tuple

Immutable grouped values, hashable composite keys, coordinates, heap items

string

Immutable character sequence, slicing, parsing, substring logic

set

Unique elements, fast existence checking, visited tracking


frozenset

Immutable set, hashable state/group representation

dict

Fast key-value mapping, frequencies, indices, grouping

defaultdict

Automatic default values, grouping, graph building, counting

Counter

Frequency counting made easy

deque

Efficient queue and both-end operations, BFS, sliding window

heapq

Min-heap, top-k, greedy extraction, Dijkstra, scheduling

bisect

Binary search on sorted lists, insertion boundaries

You might also like