This is a core course in the BSc Computer Science curriculum. It is the updated version of CS20A. Its primary focus is on the method of assessing time complexity of an algorithm, and on several algorithms that efficiently solve common problems across a wide range of domains. Hand in hand with the discussion of these algorithms, goes a discussion of the data structures that support them. Therefore each topic in this course is usually presented as a family of problems, the types of algorithmic solutions available, the necessary data structures to support them, and analyses of the tradeoffs involved with using each of these solutions.