Algorithms are fundamental to computer science. They are the essence of computer programs and lie at the core of any software system. This course will cover fundamental techniques for designing efficient computer algorithms, proving their correctness, and analyzing their performance. It will also cover a variety of application problems that use these techniques. The contents include greedy algorithms, divide and conquer algorithms, dynamic programming, network flow, NP completeness and computational intractability, approximation algorithms, and randomized algorithms. Techniques on algorithm design and analyisis will be developed by drawing on problems from across many areas of computer science and related fields.