Searching & Sorting · 28 of 36
Missing Number in AP
Fence posts are planted at equal steps but one post is missing; find it by checking whether each post stands where it should.
- Simple way
- time O(n)
room O(1) - Clever way
- time O(log n)
room O(1)
The problem, simply
You get a sorted list of numbers that go up (or down) by the same step every time, except one number in the middle was taken out. Find the missing number.
A row like this is called an arithmetic progression. The missing number is never the first or the last one, so the first and last numbers are real and tell you the step.
A story to remember it
Picture it
Each post should stand at first + i times step. Up to position 5 it matches. From position 6 on, every post is one step ahead, because 27 is missing.
- answer
- rejected
Examples
A normal case
- In
[2, 4, 8, 10, 12, 14]- Out
6
The step is (14 - 2) / 6 = 2. The row should be 2, 4, 6, 8, so 6 is missing.
Missing near the end
- In
[1, 6, 11, 16, 21, 31]- Out
26
The step is (31 - 1) / 6 = 5. After 21 comes 26, not 31.
Going down
- In
[20, 15, 5, 0]- Out
10
The step is (0 - 20) / 4 = -5. The same method works with a negative step.
Shortest possible
- In
[3, 9, 12]- Out
6
Four numbers with one taken out leaves three. The step is (12 - 3) / 3 = 3, and position 1 should be 6.
Way 1: the simple way
Find the step, then walk the row and look for the one gap that is twice as big.
- The full row had
n + 1numbers, so it hadnsteps. The step isd = (arr[n - 1] - arr[0]) / n. - Walk from left to right. The first time
arr[i + 1] - arr[i]is notd, the answer isarr[i] + d.
class Solution {
public int findMissing(int[] arr) {
int n = arr.length;
int d = (arr[n - 1] - arr[0]) / n; // n gaps in the full row
for (int i = 0; i + 1 < n; i++) {
if (arr[i + 1] - arr[i] != d) return arr[i] + d;
}
return arr[0]; // d == 0: every number is the same
}
}How long it takes: one walk, O(n). Extra room: O(1).
Way 2: the clever way
Every post before the gap stands exactly where it should: arr[i] == arr[0] + i * d. Every post after the gap is one step off. So "is post i in the right place?" is yes, yes, yes, then no, no, no. That is exactly what binary search is good at.
lo = 0,hi = n - 1. The last post is always off, so the first wrong post is somewhere in[lo, hi].- While
lo < hi: look atmid. Ifarr[mid]is where it should be, the gap is aftermid, solo = mid + 1. Otherwisemidmight be the first wrong post, sohi = mid. - When
lo == hi, that is the first wrong post. The missing number isarr[0] + lo * d.
Halve the fence until the gap is found
01 / 08
There are 8 numbers, so the full row had 8 steps. Step = (35 - 3) / 8 = 4. The last post is always out of place, so start with lo = 0 and hi = 7.
- step
- 4
- checking
- done
- answer
- rejected
class Solution {
public int findMissing(int[] arr) {
int n = arr.length;
int d = (arr[n - 1] - arr[0]) / n;
if (d == 0) return arr[0];
int lo = 0, hi = n - 1; // the last post is always out of place
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] == arr[0] + mid * d) {
lo = mid + 1; // this post is fine: gap is to the right
} else {
hi = mid; // this post slid: gap is here or to the left
}
}
return arr[0] + lo * d; // where the first wrong post should be
}
}How long it takes: the range halves each time, O(log n). Extra room: O(1).
Watch out for
- Using
hi = mid - 1when the post is wrong.midmight be the first wrong post, so keep it withhi = mid. - Overflow in
arr[0] + mid * dwhen numbers are huge. Uselongif the values can reach about a billion. - A step of 0 (all numbers equal) has no gap. Return that number, as the code does.
- The problem promises the missing number is not at either end. Without that promise the answer is not even clear:
[2, 4, 6]could be missing 0 or 8.
What interviewers ask next
- Find the missing number in
1..n(not sorted). Use the sum formulan(n + 1)/2minus the sum, or XOR all values with1..n. - Sorted array of
0..nwith one missing: the same binary search witharr[i] == ias the "in place" test. - The k-th missing positive number in a sorted array. At index
i,arr[i] - (i + 1)numbers are missing so far. Binary search on that count. - Two numbers are missing from the AP. Walk once and find the two big gaps, or binary search twice with the count of missing ones so far.
Remember this
Grown-up words: the fence row is an arithmetic progression, the step is the common difference, and "yes, yes, then no, no" is a monotonic predicate that binary search finds in O(log n).