Python for DSA Interviews

1. Basic Syntax

Blocks and indentation

Operators

Inline conditional (ternary)

Chained and nested ternary

Ternary inside a comprehension

One-line statements

Ternary vs and / or

Shorter than a ternary

is vs ==

Truthiness

Biggest trap from JS: an empty list [] and empty dict {} are falsy in Python. In JS they are truthy.

Variables, swap, unpacking

None, print, input

Exercises: Basic Syntax

  1. Predict the output of each line.

    Solution
  2. Write sign(n) that returns -1, 0 or 1 using the ternary expression.

    Solution
  3. Swap lst[i] and lst[j] in one line.

    Solution
  4. Split [1, 2, 3, 4, 5] into head (first), middle (list of the three in the middle) and tail (last) in one line.

    Solution
  5. Rewrite with one inline conditional each.

    Solution
  6. Write grade(score) with a chained ternary: 90 and above gives "A", 80 and above "B", else "C".

    Solution
  7. Why is [x for x in nums if x > 0 else 0] a SyntaxError? Fix it so negatives become 0.

    Solution

2. Loops

for loops: only for-in

range

enumerate: index and value

while, break, continue, for-else

Iterating dict and other iterables

Grid and window patterns

Do not change a list while you loop over it

Exercises: Loops

  1. Print every element of [4, 5, 6] with its index counting from 1: 1 4, 2 5, 3 6.

    Solution
  2. Given a list, print the difference between each element and the one before it. Use range.

    Solution
  3. Brute-force Two Sum: return the indices [i, j] with i < j and nums[i] + nums[j] == target, or [].

    Solution
  4. Count the cells with value 1 that have at least one neighbour (up, down, left, right) with value 1.

    Solution
  5. Use for ... else to return the first index of a list where the value is negative, or -1.

    Solution

3. Functions

Define, call, return

Functions are values

Pass a function to a function

Built-ins that take a function

Built-inThe function you pass
sorted(x, key=f), x.sort(key=f)item to sort key
min(x, key=f), max(x, key=f)item to compare key
map(f, x)item to new item
filter(f, x)item to True / False
functools.reduce(f, x, init)(accumulator, item) to new accumulator
defaultdict(f)no argument, returns the default value
heapq.nlargest(k, x, key=f)item to key
sorted(x, key=cmp_to_key(f))(a, b) to negative / 0 / positive

lambda

Return a function: closures

Late binding: closures read the variable when called, not when created. All lambdas below see the final i.

Existing functions you can pass

Dispatch table: dict of functions

functools.partial: pre-fill arguments

Arguments

Mutable default argument trap

A default value is created once, when def runs. A default list or dict is shared by all calls. Use None and create the list inside.

Arguments are passed by object reference

Scope: local, nonlocal, global

Helper functions inside functions

Decorators

Exercises: Functions

  1. Predict the output.

    Solution
  2. Write apply_n(f, x, n): apply f to x, n times. apply_n(lambda v: v * 2, 1, 5) gives 32.

    Solution
  3. Sort [("al", 90), ("bo", 85), ("cy", 90)] by score descending, then name ascending. Pass a function defined with def as the key.

    Solution
  4. Write make_counter(). Each call of the returned function gives 1, 2, 3, ...

    Solution
  5. Write compose(f, g) that returns a function computing f(g(x)).

    Solution
  6. Evaluate Reverse Polish Notation with a dict of functions. Division truncates toward zero.

    Solution
  7. Make a list of 3 functions where the function at index i returns i.

    Solution
  8. Count the even numbers in a list with an inner function and nonlocal. (Practice only. sum is simpler.)

    Solution
  9. Reverse a list in place so that the caller sees the change. Why does a = a[::-1] fail?

    Solution

4. Numbers and Booleans

int has no size limit

Division, floor, modulo

Python // and % round toward negative infinity. JS % keeps the sign of the dividend. They differ for negative numbers.

round, floor, ceil, sqrt

Float precision

Converting types

min, max, sum

bool is an int

Exercises: Numbers and Booleans

  1. Predict: -7 // 2, -7 % 3, int(-7 / 2), round(2.5), round(3.5), 2 ** -1, 10 / 5.

    Solution
  2. Reverse the digits of a signed integer. Return 0 if the result leaves the 32-bit signed range.

    Solution
  3. Given a and b, how many boxes of size b hold a items? No math import.

    Solution
  4. Count how many numbers in a list are both positive and even, in one expression.

    Solution

5. Slicing [start:stop:step]

The rules

Index table (read this first)

start and stop only

Leave a part empty

Negative start and stop

[-0:] is [0:], the whole list. If k can be 0, a[-k:] is a bug. Use a[len(a) - k:].

step

Negative step: walk backward

Reverse from index i down to index 0, including 0: use s[i::-1]. s[i:0:-1] misses index 0. s[i:-1:-1] is empty, because -1 means the last index.

Out-of-range never raises

Slice returns a new object

Slice assignment and delete (lists only)

Slicing other types

Common recipes

GoalCode
First k itemsa[:k]
Last k items (k > 0)a[-k:]
Drop the firsta[1:]
Drop the lasta[:-1]
Drop first and lasta[1:-1]
Reverse (copy)a[::-1]
Copya[:]
Even positions / odd positionsa[::2] / a[1::2]
Left half / right halfa[:len(a)//2] / a[len(a)//2:]
Rotate left by ka[k:] + a[:k]
Rotate right by ka[-k:] + a[:-k] (use k %= len(a) first)
Window of size k at ia[i:i+k]
Palindrome tests == s[::-1]
Reverse the first k chars onlys[:k][::-1] + s[k:]
Insert x at index i (new list)a[:i] + [x] + a[i:]
Remove index i (new list)a[:i] + a[i+1:]

Slice objects (rare)

Exercises: Slicing

  1. Predict each value.

    Solution
  2. Write last_k(a, k) that returns the last k items and works when k == 0.

    Solution
  3. Write the slice that returns "dcba" from "abcdef". Then the slice that returns "dcb".

    Solution
  4. Rotate a list left by k. Return a new list. Handle k larger than the length.

    Solution
  5. Split a list into chunks of size k. The last chunk can be shorter.

    Solution
  6. Reverse each word, keep the word order: "ab cd" gives "ba dc".

    Solution
  7. Reverse only the first k characters of a string: ("abcdef", 3) gives "cbadef".

    Solution
  8. Reverse a list in place in one line, without .reverse().

    Solution
  9. From a 2D grid, get the second column as a list.

    Solution

6. Strings

Indexing and slicing

JS to Python methods

JSPython
s.lengthlen(s)
s.charAt(i)s[i]
s.substring(a, b)s[a:b]
s.indexOf(x) (-1 if missing)s.find(x) (-1) or s.index(x) (raises ValueError)
s.includes(x)x in s
s.split("")list(s)
s.split(",")s.split(",")
arr.join(",")",".join(arr) (join lives on the separator; items must be str)
s.trim()s.strip()
s.toUpperCase()s.upper()
s.startsWith(x)s.startswith(x)
s.replaceAll(a, b)s.replace(a, b) (replaces ALL by default)
s.repeat(3)s * 3
s.charCodeAt(i)ord(s[i])
String.fromCharCode(n)chr(n)
s.padStart(5, "0")s.zfill(5) or s.rjust(5, "0")
s.split("").reverse().join("")s[::-1]

split, join, strip

find, count, replace, startswith

Character tests

ord, chr, alphabet tricks

f-strings

Sequence operations on strings

Building and converting

Two-pointer palindrome

Exercises: Strings

  1. Valid palindrome: ignore case and non-alphanumeric characters.

    Solution
  2. Valid anagram: are a and b made of the same letters?

    Solution
  3. Return the index of the first non-repeating character, or -1.

    Solution
  4. Reverse the words of a sentence. Collapse extra spaces.

    Solution
  5. Caesar cipher: shift every lowercase letter by k (wrap around).

    Solution
  6. Longest common prefix of a list of strings.

    Solution

7. Lists (Arrays)

JS array to Python list

JSPythonCost
arr.lengthlen(lst)O(1)
arr.push(x)lst.append(x)O(1)
arr.pop()lst.pop()O(1)
arr.shift()lst.pop(0) (use deque instead)O(n)
arr.unshift(x)lst.insert(0, x)O(n)
arr.includes(x)x in lstO(n)
arr.indexOf(x)lst.index(x) (raises if missing)O(n)
arr.slice(a, b)lst[a:b]O(k)
arr.concat(b), [...a, ...b]a + b, [*a, *b]O(n)
arr.splice(i, 1)lst.pop(i) or del lst[i]O(n)
arr.reverse()lst.reverse() (in place) or lst[::-1] (copy)O(n)
arr.map(f)[f(x) for x in lst]
arr.filter(f)[x for x in lst if f(x)]
arr.reduce(f, init)functools.reduce(f, lst, init) or sum
arr.some / everyany(...) / all(...)
arr.find(f)next((x for x in lst if f(x)), None)
Array(n).fill(0)[0] * n
arr.at(-1)lst[-1]
arr.join(",")",".join(map(str, lst))

Operations shared by all sequences

Index and slice

Negative indexes never raise: a[i - 1] with i = 0 silently returns the last element. Guard the bounds yourself.

Add and remove

Create, copy, 2D grids

[[0] * m] * n makes n references to the same row. Use a comprehension.

List comprehensions

map and filter: [f(x) for x in lst]

[x for x in lst if f(x) else 0] is a SyntaxError. A filter has no else. To keep every item, use the ternary form: [x if f(x) else 0 for x in lst].

Unpacking and built-in helpers

Matrix patterns

Exercises: Lists

  1. Predict.

    Solution
  2. Move all zeros to the end in place. Keep the order of the others.

    Solution
  3. Rotate the list right by k.

    Solution
  4. Rotate an n x n matrix 90 degrees clockwise.

    Solution
  5. Product of array except self (no division).

    Solution
  6. Remove duplicates from a sorted list in place. Return the new length.

    Solution

8. Tuples

What a tuple is

Sequence operations on tuples

Tuples as keys

Return several values

Exercises: Tuples

  1. Why does {[1, 2]: "x"} fail? Fix it.

    Solution
  2. Given points [(1,2),(3,4),(1,2)] return the number of distinct points.

    Solution
  3. Write a function that returns both the sum and the product of a list.

    Solution

9. Dictionary and Set

dict basics

dict methods

MethodDoesJS
d.get(k, default=None)value, or default if missing. No errormap.get(k) ?? default
d.keys()view of keysmap.keys()
d.values()view of valuesmap.values()
d.items()view of (key, value) pairsmap.entries()
d.update(other)merge. Overwrites existing keysObject.assign(o, other)
d.setdefault(k, default)return d[k]. If missing, set default first
d.pop(k, default)remove k, return its value. KeyError if missing and no default
d.popitem()remove and return the last inserted pair
d.clear()remove all itemsmap.clear()
d.copy()shallow copy{...o}
dict.fromkeys(keys, value=None)new dict. Every key gets the same value
a | b, a |= bmerge (Python 3.9+). New dict / in place{...a, ...b}

Counting and grouping

Reading g[k] on a defaultdict creates the key. To test without creating, use k in g.

Sorting and searching a dict

Adding or removing keys while you loop over a dict raises RuntimeError. Loop over list(d) or list(d.items()).

Nested dict

OrderedDict for LRU

set basics

{} is an empty dict. Make an empty set with set().

set methods

MethodDoesJS
s.add(x)add one item. No error if presentset.add(x)
s.update(it)add all items of an iterable
s.discard(x)remove x. No error if missingset.delete(x)
s.remove(x)remove x. KeyError if missing
s.pop()remove and return an arbitrary item
s.clear()remove all itemsset.clear()
s.copy()shallow copynew Set(s)
s.union(*its)new set with all items. Same as |
s.intersection(*its)new set with common items. Same as &
s.difference(*its)new set, items not in the others. Same as -
s.symmetric_difference(it)items in exactly one set. Same as ^
s.intersection_update(*its)in place &=
s.difference_update(*its)in place -=
s.symmetric_difference_update(it)in place ^=
s.issubset(it)all items of s are in it. Same as <=
s.issuperset(it)s has all items of it. Same as >=
s.isdisjoint(it)no common items

Set operations

Exercises: Dictionary and Set

  1. Two Sum in O(n): return the indices of the two numbers that add to target.

    Solution
  2. Group anagrams: ["eat","tea","tan","ate","nat","bat"] to groups.

    Solution
  3. Longest consecutive sequence in O(n). Example [100,4,200,1,3,2] gives 4.

    Solution
  4. Top K frequent elements.

    Solution
  5. Intersection of two lists, unique values.

    Solution
  6. Predict: type({}), type({1}), d = {}; d.get("a"), Counter("aab")["z"].

    Solution
  7. Subarray sum equals K: count subarrays with sum k (prefix sum + dict).

    Solution

10. Stack, Queue, Heap

Stack: use a list

Queue: use deque

BFS template (grid)

Heap: heapq

If two tuples tie on the first field, Python compares the next field. If that field is not comparable (a node object, a dict), you get TypeError. Add a unique counter: (priority, count, item).

Top-K and Dijkstra patterns

Exercises: Stack, Queue, Heap

  1. Valid parentheses for ()[]{}.

    Solution
  2. Kth largest element in a list (heap of size k).

    Solution
  3. Daily temperatures: for each day, how many days until a warmer day (0 if none)?

    Solution
  4. Sliding window maximum with a deque.

    Solution
  5. Merge k sorted lists into one sorted list with a heap.

    Solution
  6. Implement a max-heap of numbers using heapq. Show push, peek, pop.

    Solution

11. Sorting and Binary Search

sorted vs sort

key functions and multi-key sort

Custom comparator: cmp_to_key

bisect: binary search built in

Binary search templates

(lo + hi) / 2 gives a float. a[2.5] raises TypeError. Always use //.

Other helpers

Exercises: Sorting and Binary Search

  1. Sort words by frequency descending. Ties: alphabetical.

    Solution
  2. Merge overlapping intervals.

    Solution
  3. Search insert position in a sorted list (one line with bisect).

    Solution
  4. First and last position of x in a sorted list, or [-1, -1].

    Solution
  5. Largest number: arrange numbers to form the largest concatenation.

    Solution
  6. Koko eating bananas: the smallest speed k so that all piles finish within h hours.

    Solution

12. Recursion

How recursion works

Small examples

Recursion limits

Tree recursion

Divide and conquer

Backtracking template

Append a copy of the path: res.append(path[:]). res.append(path) stores the same list many times. Later path.pop() empties all of them.

How slow is recursion?

Exercises: Recursion

  1. Write sum_list(a) with recursion. No loops, no sum.

    Solution
  2. Flatten a nested list: [1, [2, [3]], 4] gives [1, 2, 3, 4].

    Solution
  3. Count how many ways to climb n stairs (1 or 2 steps) with plain recursion. What is the time cost?

    Solution
  4. All permutations of a list of distinct numbers.

    Solution
  5. Generate all valid strings of n pairs of parentheses.

    Solution
  6. Subsets that sum to target (numbers can be picked once). Prune when the sum is too large.

    Solution

13. Dynamic Programming

What DP is

Top-down: memoization

Bottom-up: tables

Question typeStart valueBase case
Count ways0dp[0] = 1
Minimumfloat("inf")dp[0] = 0
Maximum0 (or -inf if negatives exist)dp[0] = 0
Possible? (bool)Falsedp[0] = True

1D examples

2D examples

Save space

Top-down or bottom-up?

Top-down (@cache)Bottom-up (table)
WriteFast: copy the recursionNeeds the fill order
Depth limitYes (1000)No
SpeedSlower (call overhead)Faster
ComputesOnly needed statesAll states

Exercises: Dynamic Programming

  1. Why does @cache fail on f([1, 2])? Fix the call.

    Solution
  2. Coin change: fewest coins for amount, or -1.

    Solution
  3. Unique paths in an m x n grid with @cache (top-down).

    Solution
  4. Maximum subarray sum (Kadane).

    Solution
  5. Minimum path sum from the top-left to the bottom-right of a grid (move right or down).

    Solution
  6. Partition equal subset sum: can the list be split into two parts with equal sums?

    Solution

14. Classes for Linked Lists, Trees, Graphs

Class syntax

Linked list patterns

Tree patterns

Trie, Union-Find, Graph

Heap items: __lt__

A class-level mutable (class A: items = []) is shared by all instances. Create lists in __init__ with self.items = [].

Exercises: Classes

  1. Merge two sorted linked lists.

    Solution
  2. Detect a cycle in a linked list.

    Solution
  3. Check if a binary tree is a valid BST.

    Solution
  4. Implement MinStack with push, pop, top, get_min all O(1).

    Solution
  5. Number of islands (grid of "1" and "0") with DFS.

    Solution

15. Useful Modules and Input/Output

itertools

math, functools, copy, typing

Input for online assessments

Quick debugging

Exercises: Modules and I/O

  1. Input: first line n, second line n ints. Print the sum of the even ones.

    Solution
  2. Return all pairs (x, y) from a list (by position, i < j) with x + y == target, using itertools.

    Solution
  3. Answer many queries "sum of nums[l..r]" (inclusive) in O(1) each.

    Solution
  4. GCD of a whole list.

    Solution
  5. Generate all binary strings of length 3.

    Solution

16. Cheat Sheet and Gotchas

Time complexity of built-ins

TypeOperationCost
listlst[i], len, append, pop()O(1)
x in lst, index, remove, countO(n)
pop(0), insert(0, x), insert(i, x), del lst[i]O(n)
lst[a:b] (copy)O(b - a)
sort, sortedO(n log n)
min, max, sumO(n)
dict / setget, set, delete, inO(1) average
iterate, copyO(n)
dequeappend, appendleft, pop, popleftO(1)
dq[i] in the middleO(n)
heapqheappush, heappopO(log n)
h[0] peekO(1)
heapifyO(n)
strs[i], lenO(1)
slice, +, in, find, count, joinO(n)
bisectbisect_left / bisect_right (insort is O(n))O(log n)

Pick the structure

NeedUse
Fast "seen before?"set
Count items / group itemsCounter / defaultdict(list)
Value to index lookupdict
LIFO (undo, DFS, parentheses)list
FIFO (BFS, sliding window)deque
Smallest / largest so far, top-K, Dijkstraheapq
Sorted data, lower / upper boundbisect
Overlapping subproblems@cache or a dp list

JS to Python quick map

JSPython
null, undefinedNone
true / falseTrue / False
===, !====, !=
&& || !and or not
x ?? yx if x is not None else y
cond ? a : ba if cond else b
Math.floor(a / b)a // b
Math.max(...arr)max(arr)
Infinityfloat("inf")
parseInt(s)int(s)
console.log(a, b)print(a, b)
for (const x of arr)for x in arr:
for (const k in obj)for k in d:
Object.entries(o)d.items()
new Map(), {} as a map{} (dict)
new Set()set()
[...a, ...b], {...a}[*a, *b], {**a}
arr.sort((a, b) => a - b)sorted(arr) / key=
typeof xtype(x), isinstance(x, int)
this, new Foo()self, Foo()
function f(a = 1)def f(a=1):
(x) => x * 2lambda x: x * 2

Top gotchas