Один из наиболее часто задаваемых вопросов на собеседованиях — найти пропущенное число в массиве на Java, C # или любом другом языке. Такого рода вопросы задаются не только в небольших стартапах, но и в некоторых крупнейших технических компаниях, таких как Google, Amazon, Facebook, Microsoft.
В простейшей версии этого вопроса надо найти недостающий элемент в массиве целых чисел, содержащем числа от 1 до 100. Это можно легко решить, вычислив предполагаемую сумму с помощью n (n + 1) /2 и отняв от нее сумму всех существующих элементов массива. Это также один из самых быстрых и эффективных способов, но его нельзя использовать, если массив содержит более одного пропущенного числа или если массив содержит дубликаты.
Это дает интервьюеру несколько хороших намеков, чтобы проверить, может ли кандидат применить свои знания в несколько иных состояниях или нет. Поэтому, если вы справитесь с первым подходом, вас попросят найти пропущенное число в массиве с дубликатами или с несколькими пропущенными числами. Это может быть более сложно, но вы скоро обнаружите, что другой способ найти пропущенное и повторяющееся число в массиве — это отсортировать его.
В отсортированном массиве вы можете сравнить, равно ли число ожидаемому следующему числу или нет.
Кроме того, вы также можете использовать BitSet в Java для решения этой проблемы — надо перебрать все записи и использовать набор битов, чтобы запомнить, какие числа установлены, а затем проверить на 0 бит. Запись с битом 0 является отсутствующим номером.
Найти пропущенное число в массиве: решение на Java
import java.util.Arrays; import java.util.BitSet; public class MissingNumberInArray { public static void main(String args[]) { // one missing number printMissingNumber(new int[]{1, 2, 3, 4, 6}, 6); // two missing number printMissingNumber(new int[]{1, 2, 3, 4, 6, 7, 9, 8, 10}, 10); // three missing number printMissingNumber(new int[]{1, 2, 3, 4, 6, 9, 8}, 10); // four missing number printMissingNumber(new int[]{1, 2, 3, 4, 9, 8}, 10); // Only one missing number in array int[] iArray = new int[]{1, 2, 3, 5}; int missing = getMissingNumber(iArray, 5); System.out.printf("Missing number in array %s is %d %n",
Arrays.toString(iArray), missing); }
/** * A general method to find missing values from an integer array in Java. * This method will work even if array has more than one missing element. */ private static void printMissingNumber(int[] numbers, int count) { int missingCount = count - numbers.length; BitSet bitSet = new BitSet(count); for (int number : numbers) { bitSet.set(number - 1); } System.out.printf("Missing numbers in integer array %s, with total number %d is %n", Arrays.toString(numbers), count); int lastMissingIndex = 0; for (int i = 0; i < missingCount; i++) { lastMissingIndex = bitSet.nextClearBit(lastMissingIndex); System.out.println(++lastMissingIndex); } }
/** * Java method to find missing number in array of size n containing
* numbers from 1 to n only. * can be used to find missing elements on integer array of
* numbers from 1 to 100 or 1 - 1000 */ private static int getMissingNumber(int[] numbers, int totalCount) { int expectedSum = totalCount * ((totalCount + 1) / 2); int actualSum = 0; for (int i : numbers) { actualSum += i; } return expectedSum - actualSum; } }
Алгоритм с XOR
Мы можем использовать свойство XOR, чтобы получить решение этой проблемы, не беспокоясь о проблеме переполнения битов. Кроме того, XOR безопаснее и быстрее суммирования. Мы знаем свойство XOR, что XOR двух одинаковых чисел равен 0 ( A XOR A = 0). Если мы вычислим XOR всех чисел от 1 до N (это включает в себя неизвестное пропущенное число), а затем с этим результатом, XOR всех заданных чисел, общие числа будут отменены (так как A XOR A=0), и в конце мы получим пропущенное число. Если у нас нет проблемы переполнения битов, мы можем использовать как суммирование, так и алгоритмы на основе XOR, чтобы получить решение. Но алгоритм, использующий XOR, безопаснее и быстрее, чем алгоритм, который использует суммирование, вычитание и умножение. И мы можем избежать дополнительных забот, вызванных суммированием, вычитанием и умножением.
long n = 100; long a[] = new long[n]; //XOR of all numbers from 1 to n // n%4 == 0 ---> n // n%4 == 1 ---> 1 // n%4 == 2 ---> n + 1 // n%4 == 3 ---> 0 //Slower way of implementing the formula // long xor = (n % 4 == 0) ? n : (n % 4 == 1) ? 1 : (n % 4 == 2) ? n + 1 : 0; //Faster way of implementing the formula // long xor = (n>>1)&1 ^ (((n&1)>0)?1:n);
long xor = (n>>1)&1 ^ (((n&1)>0)?1:n); for (long i = 0; i < n; i++) { xor = xor ^ a[i]; } //Missing number System.out.println(xor);
Если вы нашли опечатку – выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Недавно у меня был аналогичный (не совсем тот же) вопрос в собеседовании, а также я услышал от друга, которого задали точно такой же вопрос в интервью.
Итак, вот ответ на вопрос OP и еще несколько вариантов, которые могут быть запрошены потенциально.
Пример ответов приведен в Java, потому что он заявил, что:
Предпочтительным является Java-решение.
Решение 1:
Массив чисел от 1 до 100 (оба включительно)… Числа случайным образом добавляются в массив, но в массиве
имеется один случайный пустой слот,
public static int findMissing1(int [] arr){
int sum = 0;
for(int n : arr){
sum += n;
}
return (100*(100+1)/2) - sum;
}
Объяснение:
Это решение (как и многие другие решения, размещенные здесь) основано на формуле Triangular number
, которая дает нам сумму всех натуральных чисел из 1 до n
(в этом случае n
равно 100). Теперь, когда мы знаем сумму, которая должна быть от 1 до 100, нам просто нужно вычесть фактическую сумму существующих чисел в заданном массиве.
Решение 2:
Массив чисел от 1 до n (это означает, что максимальное число неизвестно)
public static int findMissing2(int [] arr){
int sum = 0, max = 0;
for(int n : arr){
sum += n;
if(n > max) max = n;
}
return (max*(max+1)/2) - sum;
}
Объяснение:
В этом решении, поскольку максимальное число не задано – нам нужно его найти. После нахождения максимального числа – логика такая же.
Решение 3:
Массив чисел от 1 до n (максимальное число неизвестно), в массиве
имеется два случайных пустых слота:
public static int [] findMissing3(int [] arr){
int sum = 0, max = 0, misSum;
int [] misNums = {};//empty by default
for(int n : arr){
sum += n;
if(n > max) max = n;
}
misSum = (max*(max+1)/2) - sum;//Sum of two missing numbers
for(int n = Math.min(misSum, max-1); n > 1; n--){
if(!contains(n, arr))misNums = new int[]{n, misSum-n};
}
return misNums;
}
private static boolean contains(int num, int [] arr){
for(int n : arr){
if(n == num)return true;
}
return false;
}
Объяснение:
В этом решении максимальное число не задано (как в предыдущем), но также может отсутствовать два числа, а не одно. Итак, сначала мы находим сумму недостающих чисел – с той же логикой, что и раньше. Второе обнаружение меньшего числа между отсутствующей суммой и последним (возможно) отсутствующим числом – для уменьшения ненужного поиска. В-третьих, поскольку Java
Array (а не коллекция) не имеет методов как indexOf
или contains
, я добавил небольшой метод повторного использования для этой логики. В-четвертых, когда первое пропущенное число найдено, второе – это вычитание из недостающей суммы.
Если отсутствует только одно число, тогда второе число в массиве будет равно нулю.
Примечание
Если вам нужны примеры из других языков или других интересных вариантов этого вопроса, вы можете проверить мой репозиторий Github
для Интервью с вопросами и ответами.
Быстрый способ найти недостающее число в массиве чисел
У меня есть массив чисел от 1 до 100 (включительно). Размер массива 100. Числа случайным образом добавляются в массив, но в массиве есть один случайный пустой слот.
Каков самый быстрый способ найти этот слот, а также номер, который должен быть помещен в слот? Решение Java предпочтительнее.
30 ответов
вы можете сделать это в O (n). Перебираем массив и вычислить сумму всех чисел. Теперь сумма натуральных чисел от 1 до N может быть выражена как Nx(N+1)/2
. В вашем случае N=100.
вычесть сумму массива из Nx(N+1)/2
, где N=100.
это недостающее число. Пустой слот может быть обнаружен во время итерации, в которой вычисляется сумма.
// will be the sum of the numbers in the array.
int sum = 0;
int idx = -1;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
{
idx = i;
}
else
{
sum += arr[i];
}
}
// the total sum of numbers between 1 and arr.length.
int total = (arr.length + 1) * arr.length / 2;
System.out.println("missing number is: " + (total - sum) + " at index " + idx);
мы можем использовать операцию XOR, которая безопаснее суммирования, потому что в языках программирования, если данный вход большой, он может переполниться и может дать неправильный ответ.
прежде чем перейти к решению, знать, что A xor A = 0
. Поэтому, если мы XOR два одинаковых числа значение равно 0.
Теперь, XORing [1..n] с элементами, присутствующими в массиве, отменяет одинаковые числа. Так что в конце мы получим недостающий номер.
// Assuming that the array contains 99 distinct integers between 1..99
// and empty slot value is zero
int XOR = 0;
for(int i=0; i<100; i++) {
if (ARRAY[i] != 0)
XOR ^= ARRAY[i];
XOR ^= (i + 1);
}
return XOR;
long n = 100;
int a[] = new int[n];
//XOR of all numbers from 1 to n
// n%4 == 0 ---> n
// n%4 == 1 ---> 1
// n%4 == 2 ---> n + 1
// n%4 == 3 ---> 0
long xor = (n % 4 == 0) ? n : (n % 4 == 1) ? 1 : (n % 4 == 2) ? n + 1 : 0;
for (long i = 1; i <= n; i++)
{
xor = xor ^ a[i];
}
//Missing number
System.out.println(xor);
вот простая программа для поиска недостающих чисел в целочисленном массиве
ArrayList<Integer> arr = new ArrayList<Integer>();
int a[] = { 1,3,4,5,6,7,10 };
int j = a[0];
for (int i=0;i<a.length;i++)
{
if (j==a[i])
{
j++;
continue;
}
else
{
arr.add(j);
i--;
j++;
}
}
System.out.println("missing numbers are ");
for(int r : arr)
{
System.out.println(" " + r);
}
5050 – (сумма всех значений в массиве) = недостающее количество
int sum = 0;
int idx = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) idx = i; else sum += arr[i];
}
System.out.println("missing number is: " + (5050 - sum) + " at index " + idx);
по аналогичному сценарию,если массив уже отсортирован, он не включает дубликаты и только один номер отсутствует, можно найти это отсутствующее число в log (n) time, используя бинарный поиск.
public static int getMissingInt(int[] intArray, int left, int right) {
if (right == left + 1) return intArray[right] - 1;
int pivot = left + (right - left) / 2;
if (intArray[pivot] == intArray[left] + (intArray[right] - intArray[left]) / 2 - (right - left) % 2)
return getMissingInt(intArray, pivot, right);
else
return getMissingInt(intArray, left, pivot);
}
public static void main(String args[]) {
int[] array = new int[]{3, 4, 5, 6, 7, 8, 10};
int missingInt = getMissingInt(array, 0, array.length-1);
System.out.println(missingInt); //it prints 9
}
3
автор: Konstantinos Chalkias
Это C#, но это должно быть довольно близко к тому, что вам потребуется:
int sumNumbers = 0;
int emptySlotIndex = -1;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
emptySlotIndex = i;
sumNumbers += arr[i];
}
int missingNumber = 5050 - sumNumbers;
ну, используйте фильтр цветения.
int findmissing(int arr[], int n)
{
long bloom=0;
int i;
for(i=0; i<;n; i++)bloom+=1>>arr[i];
for(i=1; i<=n, (bloom<<i & 1); i++);
return i;
}
решение, которое не включает повторяющиеся дополнения или, возможно, формула n(n+1)/2 не доходит до вас во время интервью, например.
вы должны использовать массив из 4 ints (32 бита) или 2 ints (64 бита). Инициализировать последний int с помощью (-1 & ~(1 > 3. (биты, которые выше 100, установлены в 1) или вы можете установить биты выше 100, используя цикл for.
- пройдите через массив чисел и установите 1 для позиции бита, соответствующей номеру (например, 71 будет установлен на 3-м int на 7-м бит слева направо)
- пройдите через массив из 4 ints(32-разрядная версия) или 2 ints (64-разрядная версия)
public int MissingNumber(int a[])
{
int bits = sizeof(int) * 8;
int i = 0;
int no = 0;
while(a[i] == -1)//this means a[i]'s bits are all set to 1, the numbers is not inside this 32 numbers section
{
no += bits;
i++;
}
return no + bits - Math.Log(~a[i], 2);//apply NOT (~) operator to a[i] to invert all bits, and get a number with only one bit set (2 at the power of something)
}
пример: (32-разрядная версия) допустим, что отсутствует число 58. Это означает, что 26-й бит (слева направо) второго целого числа имеет значение 0.
первый int равен -1 (все биты установлены), поэтому мы переходим ко второму и добавляем к “нет” число 32. Второй int отличается от -1 (бит не установлен) Итак, применяя оператор NOT ( ~ ) к числу, мы получаем 64. Возможные числа-2 при мощности x, и мы можем вычислить x, используя log on base 2; в этом случае мы получим log2(64) = 6 => 32 + 32 – 6 = 58.
надеюсь, что это помогает.
Это не проблема поиска. Работодатель интересуется, есть ли у вас понимание контрольной суммы. Вам может понадобиться двоичный файл или цикл for или что-то еще, если вы ищете несколько уникальных целых чисел, но вопрос предусматривает “один случайный пустой слот.- В данном случае мы можем использовать сумму потока. Условие: “числа случайным образом добавляются в массив” бессмысленно без более подробной информации. Вопрос не предполагает, что массив должен начинаться с целого числа 1 и поэтому допускает начало смещения целое число.
int[] test = {2,3,4,5,6,7,8,9,10, 12,13,14 };
/*get the missing integer*/
int max = test[test.length - 1];
int min = test[0];
int sum = Arrays.stream(test).sum();
int actual = (((max*(max+1))/2)-min+1);
//Find:
//the missing value
System.out.println(actual - sum);
//the slot
System.out.println(actual - sum - min);
время успеха: 0.18 память: 320576 сигнал: 0
Я нашел это красивое решение здесь:
public class MissingNumberInArray
{
//Method to calculate sum of 'n' numbers
static int sumOfNnumbers(int n)
{
int sum = (n * (n+1))/ 2;
return sum;
}
//Method to calculate sum of all elements of array
static int sumOfElements(int[] array)
{
int sum = 0;
for (int i = 0; i < array.length; i++)
{
sum = sum + array[i];
}
return sum;
}
public static void main(String[] args)
{
int n = 8;
int[] a = {1, 4, 5, 3, 7, 8, 6};
//Step 1
int sumOfNnumbers = sumOfNnumbers(n);
//Step 2
int sumOfElements = sumOfElements(a);
//Step 3
int missingNumber = sumOfNnumbers - sumOfElements;
System.out.println("Missing Number is = "+missingNumber);
}
}
поиск недостающего числа из ряда чисел. Чертенок следует помнить.
- массив должен быть отсортирован..
- функция не работает на нескольких пропусках.
-
последовательность должна быть AP.
public int execute2(int[] array) { int diff = Math.min(array[1]-array[0], array[2]-array[1]); int min = 0, max = arr.length-1; boolean missingNum = true; while(min<max) { int mid = (min + max) >>> 1; int leftDiff = array[mid] - array[min]; if(leftDiff > diff * (mid - min)) { if(mid-min == 1) return (array[mid] + array[min])/2; max = mid; missingNum = false; continue; } int rightDiff = array[max] - array[mid]; if(rightDiff > diff * (max - mid)) { if(max-mid == 1) return (array[max] + array[mid])/2; min = mid; missingNum = false; continue; } if(missingNum) break; } return -1; }
1
автор: Vrajendra Singh Mandloi
Я думаю, что самым простым и, возможно, самым эффективным решением было бы зациклить все записи и использовать битовый набор, чтобы запомнить, какие числа установлены, а затем проверить на 0 бит. Запись с 0 бита недостающее число.
эта программа находит недостающие цифры
<?php
$arr_num=array("1","2","3","5","6");
$n=count($arr_num);
for($i=1;$i<=$n;$i++)
{
if(!in_array($i,$arr_num))
{
array_push($arr_num,$i);print_r($arr_num);exit;
}
}
?>
одна вещь, которую вы можете сделать, это сортировать числа, используя быструю сортировку, например. Затем используйте цикл for для итерации по отсортированному массиву от 1 до 100. На каждой итерации вы сравниваете число в массиве с приращением цикла for, если обнаружите, что приращение индекса не совпадает со значением массива, вы нашли отсутствующее число, а также отсутствующий индекс.
Ниже приведено решение для поиска всех недостающих чисел из заданного массива:
public class FindMissingNumbers {
/**
* The function prints all the missing numbers from "n" consecutive numbers.
* The number of missing numbers is not given and all the numbers in the
* given array are assumed to be unique.
*
* A similar approach can be used to find all no-unique/ unique numbers from
* the given array
*
* @param n
* total count of numbers in the sequence
* @param numbers
* is an unsorted array of all the numbers from 1 - n with some
* numbers missing.
*
*/
public static void findMissingNumbers(int n, int[] numbers) {
if (n < 1) {
return;
}
byte[] bytes = new byte[n / 8];
int countOfMissingNumbers = n - numbers.length;
if (countOfMissingNumbers == 0) {
return;
}
for (int currentNumber : numbers) {
int byteIndex = (currentNumber - 1) / 8;
int bit = (currentNumber - byteIndex * 8) - 1;
// Update the "bit" in bytes[byteIndex]
int mask = 1 << bit;
bytes[byteIndex] |= mask;
}
for (int index = 0; index < bytes.length - 2; index++) {
if (bytes[index] != -128) {
for (int i = 0; i < 8; i++) {
if ((bytes[index] >> i & 1) == 0) {
System.out.println("Missing number: " + ((index * 8) + i + 1));
}
}
}
}
// Last byte
int loopTill = n % 8 == 0 ? 8 : n % 8;
for (int index = 0; index < loopTill; index++) {
if ((bytes[bytes.length - 1] >> index & 1) == 0) {
System.out.println("Missing number: " + (((bytes.length - 1) * 8) + index + 1));
}
}
}
public static void main(String[] args) {
List<Integer> arrayList = new ArrayList<Integer>();
int n = 128;
int m = 5;
for (int i = 1; i <= n; i++) {
arrayList.add(i);
}
Collections.shuffle(arrayList);
for (int i = 1; i <= 5; i++) {
System.out.println("Removing:" + arrayList.remove(i));
}
int[] array = new int[n - m];
for (int i = 0; i < (n - m); i++) {
array[i] = arrayList.get(i);
}
System.out.println("Array is: " + Arrays.toString(array));
findMissingNumbers(n, array);
}
}
допустим, у вас есть n как 8, и наши номера варьируются от 0-8 для этого примера
мы можем представить двоичное представление всех 9 чисел следующим образом
Ноль ноль ноль ноль
Ноль ноль ноль один
Ноль ноль десять
Ноль ноль одиннадцать
Ноль сто
Ноль сто один
Ноль сто десять
Ноль сто одиннадцать
1000
в приведенной выше последовательности нет отсутствующих чисел, и в каждом столбце количество нулей и единиц совпадает, однако, как только вы удалите значение 1, скажем, 3, мы получим баланс в количестве 0 и 1 по столбцам. Если число 0 в столбце равно число 1 в этой битовой позиции, то эта битовая позиция будет 1. Мы тестируем биты слева направо и на каждой итерации выбрасываем половину массива для тестирования следующего бита, либо нечетные значения массива, либо четные значения массива выбрасываются на каждой итерации в зависимости от того, какой бит нам не хватает.
приведенное ниже решение находится в C++
int getMissingNumber(vector<int>* input, int bitPos, const int startRange)
{
vector<int> zeros;
vector<int> ones;
int missingNumber=0;
//base case, assume empty array indicating start value of range is missing
if(input->size() == 0)
return startRange;
//if the bit position being tested is 0 add to the zero's vector
//otherwise to the ones vector
for(unsigned int i = 0; i<input->size(); i++)
{
int value = input->at(i);
if(getBit(value, bitPos) == 0)
zeros.push_back(value);
else
ones.push_back(value);
}
//throw away either the odd or even numbers and test
//the next bit position, build the missing number
//from right to left
if(zeros.size() <= ones.size())
{
//missing number is even
missingNumber = getMissingNumber(&zeros, bitPos+1, startRange);
missingNumber = (missingNumber << 1) | 0;
}
else
{
//missing number is odd
missingNumber = getMissingNumber(&ones, bitPos+1, startRange);
missingNumber = (missingNumber << 1) | 1;
}
return missingNumber;
}
на каждой итерация мы уменьшаем наше входное пространство на 2, i.e N, N/2, N/4 … = O (log N), с пробелом O(N)
//Test cases
[1] when missing number is range start
[2] when missing number is range end
[3] when missing number is odd
[4] when missing number is even
решение с PHP $n = 100;
$n*($n+1)/2 - array_sum($array) = $missing_number
и array_search($missing_number)
даст индекс отсутствующего числа
0
автор: Saurabh Chandra Patel
function solution($A) {
// code in PHP5.5
$n=count($A);
for($i=1;$i<=$n;$i++) {
if(!in_array($i,$A)) {
return (int)$i;
}
}
}
========простейшее решение для отсортированного массива===========
public int getMissingNumber(int[] sortedArray)
{
int missingNumber = 0;
int missingNumberIndex=0;
for (int i = 0; i < sortedArray.length; i++)
{
if (sortedArray[i] == 0)
{
missingNumber = (sortedArray[i + 1]) - 1;
missingNumberIndex=i;
System.out.println("missingNumberIndex: "+missingNumberIndex);
break;
}
}
return missingNumber;
}
здесь сложность программы занимает время O(logn) и сложность пространства O (logn)
public class helper1 {
public static void main(String[] args) {
int a[] = {1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12};
int k = missing(a, 0, a.length);
System.out.println(k);
}
public static int missing(int[] a, int f, int l) {
int mid = (l + f) / 2;
//if first index reached last then no element found
if (a.length - 1 == f) {
System.out.println("missing not find ");
return 0;
}
//if mid with first found
if (mid == f) {
System.out.println(a[mid] + 1);
return a[mid] + 1;
}
if ((mid + 1) == a[mid])
return missing(a, mid, l);
else
return missing(a, f, mid);
}
}
public class MissingNumber {
public static void main(String[] args) {
int array[] = {1,2,3,4,6};
int x1 = getMissingNumber(array,6);
System.out.println("The Missing number is: "+x1);
}
private static int getMissingNumber(int[] array, int i) {
int acctualnumber =0;
int expectednumber = (i*(i+1)/2);
for (int j : array) {
acctualnumber = acctualnumber+j;
}
System.out.println(acctualnumber);
System.out.println(expectednumber);
return expectednumber-acctualnumber;
}
}
0
автор: Manash Ranjan Dakua
недавно у меня был подобный (не точно такой же) вопрос на собеседовании, а также я слышал от друга, который был задан точно такой же вопрос в интервью.
Итак, вот ответ на вопрос OP и еще несколько вариантов, которые можно потенциально задать.
Пример ответов приведен в Java, потому что, он заявил, что:
предпочтительнее решение Java.
решение 1:
массив чисел от 1 до 100 (включительно) … Числа случайным образом добавляются в массив, но в массиве есть один случайный пустой слот
public static int findMissing1(int [] arr){
int sum = 0;
for(int n : arr){
sum += n;
}
return (100*(100+1)/2) - sum;
}
объяснение:
Это решение (как и многие другие решения, размещенные здесь) основано на Формуле Triangular number
, что дает нам сумму всех натуральных чисел от 1 до n
(в данном случае n
is 100). Теперь, когда мы знаем сумму, которая должна быть от 1 до 100 – нам просто нужно вычесть фактическую сумму существующих чисел в данном массиве.
решение 2:
массив чисел от 1 до n (это означает, что максимальное число неизвестно)
public static int findMissing2(int [] arr){
int sum = 0, max = 0;
for(int n : arr){
sum += n;
if(n > max) max = n;
}
return (max*(max+1)/2) - sum;
}
объяснение:
В этом решении, поскольку максимальное число не задано – нам нужно его найти. После нахождения максимального числа-логика та же.
решение 3:
массив чисел от 1 до n (максимальное число неизвестно), есть два случайных пустых слота в массиве
public static int [] findMissing3(int [] arr){
int sum = 0, max = 0, misSum;
int [] misNums = {};//empty by default
for(int n : arr){
sum += n;
if(n > max) max = n;
}
misSum = (max*(max+1)/2) - sum;//Sum of two missing numbers
for(int n = Math.min(misSum, max-1); n > 1; n--){
if(!contains(n, arr))misNums = new int[]{n, misSum-n};
}
return misNums;
}
private static boolean contains(int num, int [] arr){
for(int n : arr){
if(n == num)return true;
}
return false;
}
объяснение:
В этом решении максимальное число не задано (как и в предыдущем), но оно также может отсутствовать из двух чисел, а не одного. Итак, сначала мы находим сумму недостающих чисел-с той же логикой, что и раньше. Второй поиск меньшего числа между недостающей суммой и последней (возможно) missing number-уменьшить ненужный поиск. Третий с Java
массив s (не коллекция) не имеет методов as indexOf
или contains
, я добавил небольшой многоразовый метод для этой логики. В-четвертых, когда первое отсутствующее число найдено, второе вычитается из недостающей суммы.
Если отсутствует только одно число, то второе число в массиве будет равно нулю.
Примечание
если вы хотите примеры в другие языки или другой интересные вариации этого вопроса, вы можете проверить мои Github
хранилище интервью вопросы и ответы.
использовать формулу суммы,
class Main {
// Function to ind missing number
static int getMissingNo (int a[], int n) {
int i, total;
total = (n+1)*(n+2)/2;
for ( i = 0; i< n; i++)
total -= a[i];
return total;
}
/* program to test above function */
public static void main(String args[]) {
int a[] = {1,2,4,5,6};
int miss = getMissingNo(a,5);
System.out.println(miss);
}
}
ссылка http://www.geeksforgeeks.org/find-the-missing-number/
simple solution with test data :
class A{
public static void main(String[] args){
int[] array = new int[200];
for(int i=0;i<100;i++){
if(i != 51){
array[i] = i;
}
}
for(int i=100;i<200;i++){
array[i] = i;
}
int temp = 0;
for(int i=0;i<200;i++){
temp ^= array[i];
}
System.out.println(temp);
}
}
//Array is shorted and if writing in C/C++ think of XOR implementations in java as follows.
int num=-1;
for (int i=1; i<=100; i++){
num =2*i;
if(arr[num]==0){
System.out.println("index: "+i+" Array position: "+ num);
break;
}
else if(arr[num-1]==0){
System.out.println("index: "+i+ " Array position: "+ (num-1));
break;
}
}// use Rabbit and tortoise race, move the dangling index faster,
//learnt from Alogithimica, Ameerpet, hyderbad**
Если массив заполнен случайным образом, то в лучшем случае вы можете выполнить линейный поиск в o(n) сложности. Однако мы могли бы улучшить сложность до O (log n) путем подхода divide and conquer, аналогичного быстрой сортировке, как указано гири, учитывая, что числа были в порядке возрастания/убывания.
теперь я слишком резок с большими обозначениями O, но не могли бы вы также сделать что-то вроде (в Java)
for (int i = 0; i < numbers.length; i++) {
if(numbers[i] != i+1){
System.out.println(i+1);
}
}
где numbers-массив с вашими номерами от 1-100.
Из моего прочтения вопроса он не сказал, когда записать недостающее число.
альтернативно, если вы можете выбросить значение i+1 в другой массив и распечатать его после итерации.
конечно, это может не соответствовать правилам времени и пространства. Как я и сказал. Мне пришлось сильно освежить в большой О.
еще один вопрос домашней работы. Последовательный поиск-лучшее, что вы можете сделать. Что касается решения Java, считайте это упражнением для читателя. : P
Let the given array be A with length N. Lets assume in the given array, the single empty slot is filled with 0.
We can find the solution for this problem using many methods including algorithm used in Counting sort
. But, in terms of efficient time and space usage, we have two algorithms. One uses mainly summation, subtraction and multiplication. Another uses XOR. Mathematically both methods work fine. But programatically, we need to assess all the algorithms with main measures like
- Limitations(like input values are large(
A[1...N]
) and/or number of
input values is large(N
)) - Number of condition checks involved
- Number and type of mathematical operations involved
etc. This is because of the limitations in time and/or hardware(Hardware resource limitation) and/or software(Operating System limitation, Programming language limitation, etc), etc. Lets list and assess the pros and cons of each one of them.
Algorithm 1 :
In algorithm 1, we have 3 implementations.
-
Calculate the total sum of all the numbers(this includes the unknown missing number) by using the mathematical formula(
1+2+3+...+N=(N(N+1))/2
). Here,N=100
. Calculate the total sum of all the given numbers. Subtract the second result from the first result will give the missing number.Missing Number = (N(N+1))/2) - (A[1]+A[2]+...+A[100])
-
Calculate the total sum of all the numbers(this includes the unknown missing number) by using the mathematical formula(
1+2+3+...+N=(N(N+1))/2
). Here,N=100
. From that result, subtract each given number gives the missing number.Missing Number = (N(N+1))/2)-A[1]-A[2]-...-A[100]
(
Note:
Even though the second implementation’s formula is derived from first, from the mathematical point of view both are same. But from programming point of view both are different because the first formula is more prone to bit overflow than the second one(if the given numbers are large enough). Even though addition is faster than subtraction, the second implementation reduces the chance of bit overflow caused by addition of large values(Its not completely eliminated, because there is still very small chance since (N+1
) is there in the formula). But both are equally prone to bit overflow by multiplication. The limitation is both implementations give correct result only ifN(N+1)<=MAXIMUM_NUMBER_VALUE
. For the first implementation, the additional limitation is it give correct result only ifSum of all given numbers<=MAXIMUM_NUMBER_VALUE
.) -
Calculate the total sum of all the numbers(this includes the unknown missing number) and subtract each given number in the same loop in parallel. This eliminates the risk of bit overflow by multiplication but prone to bit overflow by addition and subtraction.
//ALGORITHM
missingNumber = 0;
foreach(index from 1 to N)
{
missingNumber = missingNumber + index;
//Since, the empty slot is filled with 0,
//this extra condition which is executed for N times is not required.
//But for the sake of understanding of algorithm purpose lets put it.
if (inputArray[index] != 0)
missingNumber = missingNumber - inputArray[index];
}
In a programming language(like C, C++, Java, etc), if the number of bits representing a integer data type is limited, then all the above implementations are prone to bit overflow because of summation, subtraction and multiplication, resulting in wrong result in case of large input values(A[1...N]
) and/or large number of input values(N
).
Algorithm 2 :
We can use the property of XOR to get solution for this problem without worrying about the problem of bit overflow. And also XOR is both safer and faster than summation. We know the property of XOR that XOR of two same numbers is equal to 0(A XOR A = 0
). If we calculate the XOR of all the numbers from 1 to N(this includes the unknown missing number) and then with that result, XOR all the given numbers, the common numbers get canceled out(since A XOR A=0
) and in the end we get the missing number. If we don’t have bit overflow problem, we can use both summation and XOR based algorithms to get the solution. But, the algorithm which uses XOR is both safer and faster than the algorithm which uses summation, subtraction and multiplication. And we can avoid the additional worries caused by summation, subtraction and multiplication.
In all the implementations of algorithm 1, we can use XOR instead of addition and subtraction.
Lets assume, XOR(1...N) = XOR of all numbers from 1 to N
Implementation 1 => Missing Number = XOR(1...N) XOR (A[1] XOR A[2] XOR...XOR A[100])
Implementation 2 => Missing Number = XOR(1...N) XOR A[1] XOR A[2] XOR...XOR A[100]
Implementation 3 =>
//ALGORITHM
missingNumber = 0;
foreach(index from 1 to N)
{
missingNumber = missingNumber XOR index;
//Since, the empty slot is filled with 0,
//this extra condition which is executed for N times is not required.
//But for the sake of understanding of algorithm purpose lets put it.
if (inputArray[index] != 0)
missingNumber = missingNumber XOR inputArray[index];
}
All three implementations of algorithm 2 will work fine(from programatical point of view also). One optimization is, similar to
1+2+....+N = (N(N+1))/2
We have,
1 XOR 2 XOR .... XOR N = {N if REMAINDER(N/4)=0, 1 if REMAINDER(N/4)=1, N+1 if REMAINDER(N/4)=2, 0 if REMAINDER(N/4)=3}
We can prove this by mathematical induction. So, instead of calculating the value of XOR(1…N) by XOR all the numbers from 1 to N, we can use this formula to reduce the number of XOR operations.
Also, calculating XOR(1…N) using above formula has two implementations. Implementation wise, calculating
// Thanks to https://a3nm.net/blog/xor.html for this implementation
xor = (n>>1)&1 ^ (((n&1)>0)?1:n)
is faster than calculating
xor = (n % 4 == 0) ? n : (n % 4 == 1) ? 1 : (n % 4 == 2) ? n + 1 : 0;
So, the optimized Java code is,
long n = 100;
long a[] = new long[n];
//XOR of all numbers from 1 to n
// n%4 == 0 ---> n
// n%4 == 1 ---> 1
// n%4 == 2 ---> n + 1
// n%4 == 3 ---> 0
//Slower way of implementing the formula
// long xor = (n % 4 == 0) ? n : (n % 4 == 1) ? 1 : (n % 4 == 2) ? n + 1 : 0;
//Faster way of implementing the formula
// long xor = (n>>1)&1 ^ (((n&1)>0)?1:n);
long xor = (n>>1)&1 ^ (((n&1)>0)?1:n);
for (long i = 0; i < n; i++)
{
xor = xor ^ a[i];
}
//Missing number
System.out.println(xor);
I like to use standard recursive queries for this.
with nums (a, max_a) as (
select min(a), max(a) from test1
union all
select a + 1, max_a from nums where a < max_a
)
select n.a
from nums n
where not exists (select 1 from test1 t where t.a = n.a)
order by n.a
The
with
clause takes the minimum and maximum value of
a
in the table, and generates all numbers in between. Then, the outer query filters on those that do not exist in the table.
If you want to generate ranges of missing numbers instead of a comprehensive list, you can use window functions instead:
select a + 1 start_a, lead_a - 1 end_a
from (
select a, lead(a) over(order by a) lead_a
from test1
) t
where lead_a <> a + 1
Demo on DB Fiddle
ИЗМЕНИТЬ:
Если вы хотите, чтобы пропущенные значения находились в пределах тысяч, мы можем немного адаптировать рекурсивное решение:
with nums (a, max_a) as (
select distinct floor(a / 100) * 100 a, floor(a / 100) * 100 + 100 from test1
union all
select a + 1, max_a from nums where a < max_a
)
select n.a
from nums n
where not exists (select 1 from test1 t where t.a = n.a)
order by n.a