|
| 1 | +# Exercise I |
| 2 | + |
| 3 | +## Part a) |
| 4 | +O(n) / linear - the bound is cubic, but the rate of growth is quadratic. |
| 5 | + |
| 6 | +## Part b) |
| 7 | +O(log(n)) / logarithmic (assuming integers not floats) - `i` is cut in half each |
| 8 | +iteration, and the comparison to `x` is irrelevant. |
| 9 | + |
| 10 | +## Part c) |
| 11 | +O(sqrt(n)) - a somewhat unusual but still distinct complexity, determined fully |
| 12 | +by the outer loop. The two inner loops are both always length 8 so are dropped. |
| 13 | + |
| 14 | +## Part d) |
| 15 | +O(n*log(n)) / log-linear (or "linearithmic") - the outer loop is logarithmic, |
| 16 | +the inner is linear, and the total complexity is just their product. |
| 17 | + |
| 18 | +## Part e) |
| 19 | +O(n^3) / cubic - the outer loop is linear, the next two nested loops are both |
| 20 | +linear (in the worst/general case), and the innermost is just constant (9). |
| 21 | + |
| 22 | +## Part f) |
| 23 | +O(n) / linear - essentially equivalent to a simple for loop but recursive. |
| 24 | + |
| 25 | +## Part g) |
| 26 | +O(n) / linear - it can return early, but worst/general case is linear. |
| 27 | + |
| 28 | + |
| 29 | +# Exercise II |
| 30 | + |
| 31 | +## Part a) |
| 32 | +The naive (quadratic) approach would be a nested for loop, over `i` and `j`, |
| 33 | +that compares all possible combinations and remembers the one with the biggest |
| 34 | +difference. |
| 35 | + |
| 36 | +The correct/efficient (linear) approach is to loop over the array once tracking |
| 37 | +the minimum value and maximum difference in the same pass. |
| 38 | + |
| 39 | +Pseudocode: |
| 40 | +``` |
| 41 | +minVal = a[0] |
| 42 | +maxDiff = 0 |
| 43 | +for i in 1...n: |
| 44 | + minVal = min(minVal, a[i]) |
| 45 | + maxDiff = max(maxDiff, a[i] - minVal) |
| 46 | +return maxDiff |
| 47 | +``` |
| 48 | + |
| 49 | +## Part b) |
| 50 | +This is a conceptual question, and can be answered in a number of ways - the key |
| 51 | +insight is that you should essentially implement a binary search. Start by |
| 52 | +dropping an egg from the middle floor - if it breaks, go to the midway point |
| 53 | +between where you are and the bottom. If it doesn't, go to the midway point |
| 54 | +between where you are and the top. Either way, continue until you've narrowed |
| 55 | +on the specific lowest floor that causes it to break, and that is `f`. |
| 56 | + |
| 57 | + |
| 58 | +# Exercise III |
| 59 | + |
| 60 | +## Part a) |
| 61 | +The runtime will be O(n^2) / quadratic - there will be a linear number of passes |
| 62 | +on possible pivots, and each pivot will be compared with (on average) a linear |
| 63 | +number of other elements. |
| 64 | + |
| 65 | +## Part b) |
| 66 | +The runtime will be O(n*log(n)) / log-linear - there will be a logarithmic |
| 67 | +number of pivots, and on average a linear number of comparisons for each pivot. |
| 68 | + |
| 69 | +Note that practical implementations of Quicksort often use randomization - that |
| 70 | +is, pivots are chosen at random. The result (though it requires a bit of |
| 71 | +statistics to prove) is, on average, O(n*log(n)) performance - and the |
| 72 | +probability of the quadratic worst case is vanishingly small. |
| 73 | + |
| 74 | + |
0 commit comments