Chapter 2: Algorithm Analysis
Short Answer · Algorithms and Measurement
Question 1: The Doubling Experiment
A doubling experiment on one computer gives the running times below. Which growth class is T(n) in, and about how long will n = 32,000 take?
| n | 2,000 | 4,000 | 8,000 | 16,000 |
|---|---|---|---|---|
| time (ms) | 3 | 24 | 190 | 1,530 |
Show answer
Ratios: 24/3 = 8, 190/24 ≈ 7.9, 1530/190 ≈ 8.1 → T(2n)/T(n) ≈ 8 = 2³ → T(n) ≈ c·n³, cubic.
Estimate: T(32,000) ≈ 8 · 1,530 ≈ 12,240 ms ≈ 12 s.
The result depends on the hardware, the JVM, and the load; it covers only the inputs tried, and the algorithm must be fully implemented first. These limits are why we prefer counting primitive operations: it is hardware-independent, holds for all inputs, and needs no code to run.
Short Answer · Algorithms and Measurement
Question 2: Counting Primitive Operations
On an array of n items, how many primitive operations does countNegatives perform in the best and worst cases, and which inputs cause them? Count line by line.
int countNegatives(int[] a) { int s = 0; for (int i = 0; i < a.length; i++) if (a[i] < 0) s++; return s; }
Show answer
| Statement | Count |
|---|---|
s = 0, i = 0 | 1 + 1 |
i < a.length | n + 1 |
a[i] < 0 | n |
s++ | 0 … n |
i++ | n |
return | 1 |
Best: 3n + 4 (no negatives). Worst: 4n + 4 (every item negative). Both are Θ(n); the constants depend on the hardware, so we drop them.
Multiple Choice · Asymptotic Notation
Question 3: Growth Rates
For large n, which list orders the functions from slowest-growing to fastest-growing?
For n = 1,000: log₂n ≈ 10, n = 1,000, n log₂n ≈ 9,966, n² = 10⁶, 2ⁿ ≈ 10³⁰¹. B is the trap: for small n such as 2, 3, or 4, 2ⁿ ≤ n² can hold, but for large n 2ⁿ overtakes every polynomial (at n = 100, 2ⁿ steps take ~4·10¹³ years).
Multiple Choice · Asymptotic Notation
Question 4: Misconceptions About Asymptotic Notation
Which statement is true?
O, Ω, and Θ are notations for bounds; best, average, and worst case are a separate idea, and each can be bounded either way (B is false). log₂ n = log₁₀ n / log₁₀ 2: they differ only by a constant factor, so both are O(log n). The constant in O(1) can be large; for small n, 1000 steps of constant work are slower than n steps.
Multiple Choice · Asymptotic Notation
Question 5: Amortized Analysis
Appending to a growable array (such as ArrayList) usually takes one step; when the array is full, every item is copied to a new array twice as large (O(n)). Which statement describes this best?
The copies move 1 + 2 + 4 + … < 2n items in all; dividing the total cost of a long sequence of operations by their number gives a constant per append. A single append can still be O(n), so C is false; amortized analysis assumes no probabilities (D is false).
Multiple Choice · Asymptotic Notation
Question 6: The Worst-Case Input
hasDuplicates(a) compares every pair of items and returns true at the first equal pair. Which input gives its worst case?
With no duplicates there is never an early return, so all n(n − 1)/2 pairs are compared → Θ(n²). A and B return true on the first comparison (the best case, Θ(1)). Being sorted changes nothing by itself; in D the method stops as soon as it finds a duplicate.
Short Answer · From Code to Complexity
Question 7: From Loops to Complexity
For n = 16, what is s when the code finishes, and what is its Big O complexity?
int s = 0; for (int i = 0; i < n; i++) for (int j = 1; j < n; j *= 2) s++; for (int k = 0; k < 100; k++) s++;
Show answer
s = 164.
- The inner loop runs j = 1, 2, 4, 8 → ⌈log₂16⌉ = 4 rounds; the outer loop runs 16; nested costs multiply: 16 · 4 = 64 → O(n log n).
- The second loop runs 100 rounds regardless of n → O(1).
Costs of consecutive blocks add, and the largest wins: O(n log n) + O(1) = O(n log n). The “nested loops mean n²” rule does not apply here.
Short Answer · From Code to Complexity
Question 8: Three Loop Patterns
Roughly what is s at the end of each fragment, and what is its Big O complexity?
// (1) for (int i = n; i > 0; i /= 2) s++; // (2) for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) s++; // (3) for (int i = 0; i < n; i += 2) for (int j = 0; j < 10; j++) s++;
Show answer
(1) i halves every round: ⌊log₂ n⌋ + 1 rounds → O(log n).
(2) The inner loop runs i times: 0 + 1 + … + (n − 1) = n(n − 1)/2 → O(n²). An inner loop that depends on the outer variable does not change the class.
(3) The outer loop runs n/2 rounds, the inner a fixed 10: 5n → O(n). Nested loops do not always mean n².
Code Trace · From Code to Complexity
Question 9: Tracing Binary Search
For a = {3, 7, 11, 15, 19, 24, 30, 36}, how many rounds does binarySearch(a, 8) take, how do lo and hi change, and what does it return?
The search range is the whole array: lo = 0, hi = 7.
Round 1: mid = (0 + 7) / 2 = 3, a[3] = 15.
15 > 8 → the target is in the left half: hi = 2. Right half discarded.
Round 2: mid = (0 + 2) / 2 = 1, a[1] = 7.
7 < 8 → the target is to the right: lo = 2.
Round 3: mid = (2 + 2) / 2 = 2, a[2] = 11.
11 > 8 → hi = 1.
2 ≤ 1 is false → range empty, loop ends.
return −1 after 3 rounds. For n = 8 the worst case is ⌊log₂8⌋ + 1 = 4 rounds; for n = 10⁶, 20 → O(log n).
int binarySearch(int[] a, int target) { int lo = 0, hi = a.length - 1; while (lo <= hi) { int mid = (lo + hi) / 2; if (a[mid] == target) return mid; if (a[mid] < target) lo = mid + 1; else hi = mid - 1; } return -1; }
Multiple Choice · From Code to Complexity
Question 10: Midpoint Overflow
These lines run during a binary search on a very large array. What is the output?
int lo = 1_500_000_000; int hi = 2_000_000_000; int m1 = (lo + hi) / 2; int m2 = lo + (hi - lo) / 2; System.out.println(m1 + " " + m2);
lo + hi = 3.5·10⁹ exceeds the int limit (≈ 2.1·10⁹) and silently wraps around to a negative number; Java throws no exception on integer overflow (D is false). lo + (hi - lo) / 2 never exceeds the limit at any step, so it is safe.
Multiple Choice · Space and Correctness
Question 11: Extra Memory
Which method uses O(n) extra space? (The input array itself does not count.)
C allocates a new n-cell array to hold the result → O(n) extra memory. A, B, and D use only a few variables (the maximum, two indices, lo / hi / mid) → O(1).
Multiple Choice · Asymptotic Notation
Question 12: c₁, c₂, and n₀ for Θ
To show f(n) = 3n + 10 = Θ(n), we need c₁·n ≤ f(n) ≤ c₂·n for every n ≥ n₀. Which choice does not show this?
With c₁ ≤ 3 the lower bound always holds. Upper bound: 3n + 10 ≤ c₂·n ⇔ n ≥ 10 / (c₂ − 3). D needs n ≥ 5, and at n = 4, f(4) = 22 > 20. A (n ≥ 10), B (n ≥ 1), and C (n ≥ 2) are valid. c and n₀ are not unique; D would work with n₀ = 5.
Short Answer · Asymptotic Notation
Question 13: Proving Ω from the Definition
Let f(n) = n²/2 − 3n.
- Taking c = 1/4, show that f(n) = Ω(n²). What is the smallest n₀ for this c?
- Use the definition to show that f(n) is not O(n).
- What Θ statement can you write for f?
Show answer
1. n²/2 − 3n ≥ n²/4 ⇔ n²/4 ≥ 3n ⇔ n ≥ 12. n₀ = 12 (at n = 11, f = 27.5 < 121/4 = 30.25).
2. If c and n₀ existed, then n²/2 − 3n ≤ c·n, that is, n ≤ 2c + 6, for every n ≥ n₀; n = max(n₀, 2c + 7) breaks this → f(n) ≠ O(n).
3. f(n) ≤ n²/2 → O(n²). Together with part 1, Θ(n²): n²/4 ≤ f(n) ≤ n²/2 for n ≥ 12.
Multiple Choice · Asymptotic Notation
Question 14: Average Case Under a Distribution
Linear search runs on a 10-item array, and the target is always present. It is at position 1 with probability 0.3, at position 2 with probability 0.3, and at each of the other 8 positions with probability 0.05. If a target at position i takes i comparisons, what is the expected number of comparisons?
Expected value = Σ probability × cost = 0.3·1 + 0.3·2 + 0.05·(3 + 4 + … + 10) = 0.9 + 0.05·52 = 3.5. A assumes equal probabilities ((n + 1)/2); the average case depends on the chosen distribution. C averages only the first two positions and forgets the remaining 0.4 of probability. D is the worst case.
Short Answer · Asymptotic Notation
Question 15: Averaging in Unsuccessful Searches
Linear search runs on an array of n items. With probability q the target is absent (n comparisons); otherwise it is equally likely to be at any of the n positions (position i takes i comparisons).
- Write the expected number of comparisons in terms of n and q.
- Compute it for n = 8, q = 0.5.
- What do q = 0 and q = 1 correspond to? Which class is the average case in?
Show answer
1. If the target is present, the average is (1 + … + n) / n = (n + 1)/2; weight the two cases by their probabilities:
E = (1 − q)·(n + 1)/2 + q·n
2. E = 0.5 · 4.5 + 0.5 · 8 = 2.25 + 4 = 6.25 comparisons.
3. q = 0: the target is always present, E = (n + 1)/2. q = 1: it is never present, E = n (the worst case). For every q, E is linear → Θ(n); the distribution changes only the constant.