How do you do this? The values are unsorted but are of [1..n]
Example array [3,1,2,5,7,8]
. Answer: 4, 6
I saw this solution in
Code sample(Java) for @slider answer
/**
* get 2 missed numbers from randomly shuffled array of unique elements from [1,n]
*
* @param array - shuffled array of unique elements from [1,n], but 2 random elements was missed. len = n-2
* @return array with 2 missed elements
*/
public static int[] getMissedNumbers(int[] array) {
int sum = 0;
int fullSum = 0;
int fullProduct = 1;
int product = 1;
for (int i = 0; i < array.length + 2; i++) {
int currNaturalNumber = i + 1;
fullSum = fullSum + currNaturalNumber;
fullProduct = fullProduct * currNaturalNumber;
if (i < array.length) {
sum = sum + array[i];
product = product * array[i];
}
}
int missedSum = fullSum - sum; //firstMissedNum + secondMissedNum
int missedProduct = fullProduct / product; //firstMissedNum * secondMissedNum
//ax*x + bx + c = 0
//x = (-b +- sqrt(b*b - 4*a*c))/2*a
// -b = missedSum , c = missedProduct, a = 1
Double firstMissedNum = (missedSum + Math.sqrt(missedSum * missedSum - 4 * missedProduct)) / 2;
Double secondMissedNum = (missedSum - Math.sqrt(missedSum * missedSum - 4 * missedProduct)) / 2;
return new int[]{firstMissedNum.intValue(), secondMissedNum.intValue()};
}
and simple arrays generator for tests
public static Map.Entry generateArray(int maxN, int missedNumbersCount) {
int[] initialArr = new int[maxN];
for (int i = 0; i < maxN; i++) {
initialArr[i] = i + 1;
}
shuffleArray(initialArr);
int[] skippedNumbers = Arrays.copyOfRange(initialArr, maxN - missedNumbersCount, maxN);
int[] arrayWithoutSkippedNumbers = Arrays.copyOf(initialArr, maxN - missedNumbersCount);
return new AbstractMap.SimpleEntry<>(arrayWithoutSkippedNumbers, skippedNumbers);
}
private static void shuffleArray(int[] ar) {
Random rnd = ThreadLocalRandom.current();
for (int i = ar.length - 1; i > 0; i--) {
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}