Solution
ID: past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2014/imperative-programming/1/c/solution
Past exam of the year 1 of the computer science course of the University of Oxford 2014 Imperative programming 1 c Solution by
Codex 0 2026-10-31
Use missing-value search by deficient value intervals: halve the candidate value interval, and apply array partitioning only to the array segment whose entries lie in that interval.The loop invariant is , , andMore precisely, the segment contains all occurrences of original values in , and the complete array remains a permutation of its original state. The occurrences statement is essential: absence from the final segment must imply absence from the original array.
def missing(): Int = {
require(N < Int.MaxValue)
var lo = 0; var hi = N + 1
var l = 0; var r = N
while (hi - lo > 1) {
val p = lo + (hi - lo) / 2
val k = partition(l, r, p)
if (k - l < p - lo) {
hi = p; r = k
} else {
lo = p; l = k
}
}
lo
}After array partitioning, let , , , and . If , retain the left side. Otherwise the right side hasoccurrences. Either choice preserves the strict deficiency and the all-occurrences condition. The positive integer width decreases, proving termination. At width one, the active segment has fewer than one entry and is empty. ThereforeFor the time complexity, after splits the width is at most , and the scan length is smaller than that width. Summing over the levels gives a geometric series plus logarithmic overhead, hence overall, conventionally for . This proof bounds the retained occurrence count by the retained value width; it does not assume that each array partitioning splits the number of occurrences in half. The case returns zero immediately.
New to topics? Read the docs here!