#algorithm
#алгоритм
Вопрос:
Мне нужно найти минимальный недостающий элемент из последовательности неотрицательных целых чисел.
пример: у меня есть: 0 5 10 4 3 1
The missing element is 2.
В приведенной выше последовательности отсутствующими элементами являются 2 6 7 8 9 . Минимальный из них равен 2, поэтому ответ равен 2.
Грубая сила . Я отсортирую последовательность и получу минимальный элемент в nlogn .Я ищу лучшее решение. Любая помощь?
Комментарии:
1. Отсутствует по отношению к чему? Пожалуйста, предоставьте дополнительную информацию.
2. Отсутствует запись в последовательность.
3. @Gunner : Я добавил больше пояснений к своему примеру.
Ответ №1:
В ISO C99:
unsigned least_absent(unsigned seq_sz, unsigned seq[seq_sz])
{
bool tab[seq_sz];
memset(tab, 0, sizeof(tab));
for(unsigned i=0; i<seq_sz; i )
if(seq[i] < seq_sz)
tab[seq[i]] = true;
for(unsigned i=0; i<seq_sz; i )
if(!tab[i])
return i;
return seq_sz;
}
Это O (n) времени, O (n) памяти.
Ответ №2:
Может быть выполнено за O (n) с помощью хэш-таблицы, что означает O (n) дополнительной памяти:
- Вставьте числа в хэш-таблицу, выполняемую в O(n).
- Перейдите от нуля к максимуму списка и проверьте, существует ли это число. Первое число, которого не существует, является ответом. Это также выполняется в O(n).
Ответ №3:
list = sort(list)
last_element = list[0]
for(i = 1; i < list.size; i){
if(list[i] - last_element > 1)
return last_element 1 // return the next number after last_element
last_element = list[i]
}
return -1 // return -1 if unable to find a number
Ответ №4:
Это решение имеет O (n) пространственно-временную сложность.
def solution(A):
#Python 3.6
a = set() #to store positive numbers in the given array
b = set() #to store missing positive numbers in the given array
for item in A:
if item<=0:
continue
a.add(item)
if item in b:
b.remove(item)
if item 1 not in a:
b.add(item 1)
#if all numbers are negative in the given array
if len(a) == 0:
return 1
#if 1 is not in the given array, 1 is the answer
if 1 not in a:
return 1
return min(b)
Ответ №5:
Псевдокод:
for(int i = 0 ; i < Int.MAX ; i )
{
if(i is not in list)
{
return i
}
}
Конечно, возможно, это можно оптимизировать, но в качестве первоначального варианта, для того чтобы ваши тесты проходили (у вас ведь есть тесты, верно), это очень простое решение, которое даст вам уверенность в правильности ваших тестов, освободив вас для оптимизации в случае необходимости.
Комментарии:
1. Для нахождения максимального целого числа в этом случае потребуется o (n * 2). Это правильно?
2. Да, это выглядит примерно так. Но моя мантра всегда такова: «Сначала сделайте это правильно, а затем, если необходимо, сделайте это быстро»
Ответ №6:
Нет необходимости в сортировке.
-
Просмотрите список и найдите 2 наименьших значения, разница между которыми больше 1. (O(N)).
-
Выведите (было найдено наименьшее значение) 1.
Комментарии:
1. Как вы делаете 1. за O (n) время?
2. какова будет сложность в этом случае. nlogn min heap даст мне минимальный элемент. Это правильно?
3. Я был бы удивлен, если бы это было лучше, чем сортировка. В лучшем случае, я думаю, это было бы эквивалентно. Это не так просто, как кажется, потому что вам нужно было бы отслеживать несколько пар значений на случай, если пробел в младшей паре был заполнен позже в последовательности.
Ответ №7:
Самый простой подход, который я могу придумать, — отсортировать список, а затем просмотреть его в поисках первого пробела.
Я не уверен, что есть что-то намного проще. Даже если вы каким-то образом проанализируете список, фактически не сортируя его, вам нужно будет отслеживать пробелы, которые вы обнаружили по пути, а затем устранять их по ходу работы. Я думаю, что это, вероятно, логически эквивалентно алгоритму сортировки в любом случае. Может быть ошибочным.
Ответ №8:
Сначала отсортируйте элементы. Затем начните находить числа в вашей последовательности, например:
for (int i=0; i<numbers.length; i ) {
if (numbers[i] != i ) {
System.out.println("Missing number is: " i); break;
}
}
Комментарии:
1. Быстрая сортировка также может быть кандидатом здесь для сортировки. Или сортировка по вставке.
2. Вы предполагаете, что значение не может появляться более одного раза во входной последовательности.
3. в этом случае в вопросе должно быть конкретно указано, что 🙂
4. скорее — на собеседовании вы должны задавать соответствующие вопросы или излагать свои предположения…
Ответ №9:
Псевдокод :
a is the array
s is a sorted set (examples : a binary search tree, or a red/black tree)
insert 0 in s
for each v in a
remove v from s
insert v 1 in s
result is min(s)
Ответ №10:
- Отсортировать массив (
O(NlogN)
наихудший вариант для сортировки слиянием) - Повторяйте цикл с самого начала, пока не обнаружится разница более чем в 1 между двумя соседними элементами. (
O(N)
наихудший случай)
Ответ №11:
Если вы знаете, что повторяющихся элементов нет, вы можете выполнить за O (N log N) время с O (1) памятью:
Вы выполняете двоичный поиск, чтобы найти ответ: изначально вы знаете, что ответ находится между 0 и N-1, для каждого шага вы подсчитываете, на сколько чисел меньше k (k средний элемент сегмента двоичного поиска), если это число равно k, то эта часть последовательности завершена, поэтому вам нужно выполнить поиск в верхней части, в противном случае вам нужно выполнить поиск в нижней части.
Ответ №12:
Улучшая некоторые идеи (@Faisal Feroz, @slacker, @dahunter, @user453201): Во время прохождения по списку значений (сортировка или вставка значений в хэш / таблицу поиска), сохраняйте минимум. Затем, чтобы найти недостающий элемент, начните с этого минимума вместо 0. Небольшое улучшение, но оно все равно лучше.
Комментарии:
1. Если минимум не равен нулю, то первый отсутствующий элемент равен нулю :).