Time and Space Complexity
Table of Contents
Adapted from Hunter Schafer: https://courses.cs.washington.edu/courses/cse373/20au/lectures/4.pptx
1 Reading
Read Section 5.1.1 of Bailey (p. 81–85 of the text, 97–101 of the pdf). See the rest of Section 5.1 for examples and additional discussion.
2 Video
Here is a video lecture for the slides below.
The video contains sections on
- Learning Objectives (0:20)
- Time and space analysis helps us differentiate (1:10)
- We need a tool to analyze code that is (3:56)
- Overview: Algorithmic Analysis (6:13)
- What is a Complexity Class (7:34)
- Does Complexity Really Matter? (9:58)
- Code Modeling (11:23)
- What is an operation? (11:38)
- Code Modeling Example I (13:54)
- Code Modeling Example II (16:19)
- Finding a Big-O (19:21)
- Is it okay to throw away all that info? (21:46)
- No seriously, this is really okay? (24:15)
- Using Formal Definitions (27:16)
- Big-O Definition (28:41)
The Panopto viewer has table of contents entries for these sections: https://carleton.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=6ee55f38-7708-4db6-8b57-acb8013c47f8
3 Slides
You can download the slides in pdf or PowerPoint.
4 Practice Problems1
- Model the number of operations involved in the following code in terms of \(n\):
public int method1(int n) { int sum = 0; for (int i = n; i > 0; i -= 2) { for (int j = 0; j < n; j++) { sum++; } } return sum; }
- Model the number of operations involved in the following code in terms of \(n\):
public int method2(int n) { int sum = 0; for (int i = 1; i <= n * 2; i++) { for (int j = 1; j <= n; j++) { sum++; } } for (int j = 1; j < 100; j++) { sum++; sum++; } return sum; }
- Model the number of operations involved in running
bar
in terms of \(n\):public boolean foo(int x) { return x % 2 == 0 && x > 0; } public int bar(int n) { int sum = 0; for (int i = 0; i < n; i++) { if (foo(i)) { sum += i; } } return sum; }
- Give the big-O complexity for problems 1, 2, and 3.
- Suppose an algorithm takes exactly the given number of statements for each value below, in terms of an input size \(n\). Give the big-O bound for each algorithm, representing the closest complexity class for that algorithm based on that runtime.
- \(3n\)
- \(n + 900\)
- \(\frac{1}{2}n\log n + \log n\)
- \(n^2 - (n + n\log n + 1000)\)
- \(n^2 \log n + 2n\)
- \(\frac{1}{2}(3n + 5 + n)\)
- \((2n + 5 + n^4)/n\)
- \(n! + 2n\) (\(n!\) is \(n\)-factorial, meaning the product \(n \times (n - 1) \times (n - 2) \cdots 2 \times 1\))
5 Learning Block
- share confusions/questions in learning pods
- questions?
- form question
- practice problem 5
- timing demo
import java.util.ArrayList; import java.util.LinkedList; import edu.princeton.cs.algs4.StopwatchCPU; public class Timing { public static void main(String[] args) { StopwatchCPU watch = new StopwatchCPU(); // compare O(n) with O(1) int n = 100000; int[] nums = new int[n]; double start = watch.elapsedTime(); for (int i = 0; i < nums.length; i++) { nums[i] = i; } double end = watch.elapsedTime(); System.out.println("loop took " + (end - start) + "s"); start = watch.elapsedTime(); nums[0] = 100; end = watch.elapsedTime(); System.out.println("one assignment took " + (end - start) + "s"); ArrayList<Integer> arraylist = new ArrayList<>(); LinkedList<Integer> linkedlist = new LinkedList<>(); start = watch.elapsedTime(); // O(n^2) for (int i = 0; i < nums.length; i++) { // linear time insertion into arraylist arraylist.add(0, i); } end = watch.elapsedTime(); System.out.println("linear time insertion took " + (end - start) + "s"); start = watch.elapsedTime(); // O(n) for (int i = 0; i < nums.length; i++) { // constant time insertion into linkedlist linkedlist.add(0, i); } end = watch.elapsedTime(); System.out.println("constant time insertion took " + (end - start) + "s"); } }
Footnotes:
1
Solutions:
- \(f(n) = (3n + 3)\frac{n}{2} + 3 = \frac{3n^2 + 3n}{2} + 3\)
public int method1(int n) { int sum = 0; // +1 for (int i = n; i > 0; i -= 2) { // +1 before loop (i = n), +2 inside (i > 0, i -= 2) | for (int j = 0; j < n; j++) { // +1 before, +2 inside | | (3n + 3)(n/2) total sum++; // +1 | 3n total | } } return sum; // +1 }
- \(f(n) = 6n^2 + 8n + 400\)
public int method2(int n) { int sum = 0; // +1 for (int i = 1; i <= n * 2; i++) { // +1, +3 | for (int j = 1; j <= n; j++) { // +1, +2 | | (3n + 4)2n sum++; // +1 | 3n | } } for (int j = 1; j < 100; j++) { // +1, +2 | sum++; // +1 | 99*4 sum++; // +1 | } return sum; // +1 }
- \(f(n) = 7n + 3\)
public boolean foo(int x) { return x % 2 == 0 && x > 0; // +4 } public int bar(int n) { int sum = 0; // +1 for (int i = 0; i < n; i++) { // +1, +2 | if (foo(i)) { // see foo | 7n, assume sum += i always happens (overly pessimistic worst case) sum += i; // +1 | } } return sum; // +1 }
- \(O(n^2)\), \(O(n^2)\), \(O(n)\)
- \(O(n)\)
- \(O(n)\)
- \(O(n\log n)\)
- \(O(n^2)\)
- \(O(n^2 \log n)\)
- \(O(n)\)
- \(O(n^3)\)
- \(O(n!)\)