Repeat and Missing Number Array
Time
Space
Problem
Section titled “Problem”You are given a read only array of n integers from 1 to n.
Each integer appears exactly once except A which appears twice and B which is missing.
Return A and B.
Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
Note that in your output A should precede B.
Example:
Input:[3 1 2 5 3]
Output:[3, 4]
A = 3, B = 4Solution approach
Section titled “Solution approach”Intuition
Section titled “Intuition”Let A be the repeated number and B the missing one. Comparing the array with the ideal list 1..n gives two equations:
- Sum:
- Sum of squares:
Dividing the second difference by the first gives . With and known, both numbers follow, and no extra array or sorting is needed.
Algorithm
Section titled “Algorithm”- In one loop, accumulate
sm(sum of elements),sm2(sum of their squares) andsm4(sum of for ). - Compute
sm1 = n(n + 1) / 2andrel1 = sm1 - sm, which is . - Compute
rel2 = (sm4 - sm2) / rel1, which is . - Swap so that
rel1holds the larger value andrel2holds . - Then
x = (rel1 + rel2) / 2is the missing number andy = (rel1 - rel2) / 2is the repeated number . Return{y, x}.
Complexity
Section titled “Complexity”- Time: — one pass over the array.
- Space: — a handful of counters.
Edge cases
Section titled “Edge cases”- Large values:
A[i] * A[i]and(i + 1) * (i + 1)are computed inintbefore being added to thelong longsums, so they overflow once values pass about .
vector<int> Solution::repeatedNumber(const vector<int> &A) { long long sm = 0, sm1 = 0, sm2 = 0, sm4 = 0; long long n = A.size(); for (int i = 0; i < n; i++) { sm += A[i]; sm2 += A[i] * A[i]; sm4 += (i + 1) * (i + 1); } sm1 = (n * (n + 1ll) / 2ll); long long rel1 = sm1 - sm; long long rel2 = (sm4 - sm2) / rel1; if (rel1 < rel2) swap(rel1, rel2); long long x = (rel1 + rel2) / 2ll; long long y = (rel1 - rel2) / 2ll; vector<int> aa = {y, x}; return aa;}Give it a try first
Attempt the problem on InterviewBit — the code will still be here.