Calculating time complexity felt like memorizing answers rather than understanding analysis. These resources taught me how to derive complexity from first principles.

MIT Mathematics for Computer Science text

Chapter 13 on asymptotic notation provides the mathematical foundation. Understanding why we drop constants and lower-order terms made Big O meaningful instead of arbitrary. The summation review directly applies to loop analysis.

Cracking the Coding Interview appendix

The Big O section walks through deriving complexity for recursive functions. The recursive call counting technique works for most divide and conquer algorithms. Her examples show common mistakes and how to avoid them.

Big-O Cheat Sheet website

Seeing common data structure operations listed with their complexities built pattern recognition. I referenced this constantly while learning new structures. The sorting algorithm comparison table shows why QuickSort dominates despite worst-case issues.

Stanford CS161 lecture notes

Their recurrence relation explanations demystified analyzing recursive algorithms. The substitution method and master theorem finally made sense with their worked examples. Week three covers amortized analysis for dynamic arrays.

InterviewCake complexity article

Their space complexity explanation clarified what counts toward memory usage. The recursive call stack discussion explained why some solutions use O(n) space despite looking constant. The practical examples use real code instead of pseudocode.

Mathematical foundation plus practical application plus pattern recognition equals actual understanding. I stopped guessing and started calculating after working through these systematically. Analyzing new algorithms became mechanical rather than mysterious.