Bounds and input models
O denotes an asymptotic upper bound, Ω a lower bound, and Θ a tight bound. These do not inherently mean worst, best, or average case. Define the cost function and input size; graphs often require both vertex count V and edge count E.
Check yourself: Are you bounding worst-case cost or an expectation?
Recurrences and recursion trees
Separate recursive work from work outside recursive calls. In T(n) = 2T(n/2) + n for powers of two, each internal level contributes n, across log₂ n levels. Include leaf costs for an exact expression, not just a growth rate.
Check yourself: Does the expression satisfy the recurrence and base case?
BFS and Dijkstra
BFS uses a FIFO queue to discover vertices by edge-count distance. Dijkstra selects the smallest tentative weighted distance; its standard correctness argument requires nonnegative weights. With adjacency lists, BFS takes O(V + E), while binary-heap Dijkstra takes O((V + E) log V).
Check yourself: Are you minimizing hops or weight, and are negative weights possible?
Greedy choices need proof
Justify greedy choices through an exchange argument, cut property, or invariant showing an optimal solution can include them. For maximizing the number of nonoverlapping intervals, earliest finish time leaves room for later intervals; earliest start time need not maximize the count.
Check yourself: Can your choice replace one in an optimal solution without worsening it?
Dynamic-programming states
Define each state's meaning, base cases, and dependency order before writing transitions. For 0/1 knapsack with a one-dimensional capacity array, descending capacity prevents reuse of the current item. Ascending capacity would permit repeated use within the same item pass.
Check yourself: Could the state you read already include the current item?