Число, которое встречается только один раз в массиве
Возможный дубликат:
Поиск единственного числа в списке
Учитывая массив чисел, кроме одного числа, все остальные
дважды. Какой алгоритм должен найти этот номер, который встречается только один раз в
массив?
Пример
a[1..n] = [1,2,3,4,3,1,2]
должен возвращать 4
Ответы
Ответ 1
Пусть число, которое встречается только один раз в массиве, будет x
x <- a[1]
for i <- 2 to n
x <- x ^ a[i]
return x
Так как a ^ a = 0
и a ^ 0 = a
Число, которое происходит в паре, отменяется, и результат сохраняется в x
Рабочий код в С++
#include <iostream>
template<typename T, size_t N>
size_t size(T(&a)[N])
{
return N;
}
int main()
{
int a [] = {1,2,3,4,3,1,2};
int x = a[0];
for (size_t i = 1; i< size(a) ; ++i)
{
x = x ^ a[i];
}
std::cout << x;
}
Ответ 2
- Создать новый
int i = 0
-
XOR
каждый элемент с i
- После всех итераций ожидается число в
i
Ответ 3
Если у вас есть величины, которые не могут быть разумно протестированы (например, большие целые числа или числа, представленные как строки), альтернативный подход, который также является временем O (n), но O (n), а не O (1) пространство) было бы просто использовать хеш-таблицу. Алгоритм выглядит так:
Create a hash table of the same size as the list
For every item in the list:
If item is a key in hash table
then remove item from hash table
else add item to hash table with nominal value
At the end, there should be exactly one item in the hash table
Я бы сделал, C или С++-код, но ни один из них не имеет встроенных таблиц хеша. (Не спрашивайте меня, почему С++ не имеет хеш-таблицы в STL, но имеет хэш-карту, основанную на красно-черное дерево, потому что я понятия не имею, о чем они думают.) И, к сожалению, у меня нет компилятора С# для проверки синтаксических ошибок, поэтому я даю вам код Java. Это довольно похоже, однако.
import java.util.Hashtable;
import java.util.List;
class FindUnique {
public static <T> T findUnique(List<T> list) {
Hashtable<T,Character> ht = new Hashtable<T,Character>(list.size());
for (T item : list) {
if (ht.containsKey(item)) {
ht.remove(item);
} else {
ht.put(item,'x');
}
}
return ht.keys().nextElement();
}
}
Ответ 4
Ну, я знаю только об атрибуте Brute force, и он должен пройти весь массив и проверить
Код будет как (в С#):
k=0;
for(int i=0 ; i < array.Length ; i++)
{
k ^= array[i];
}
return k;
Ответ 5
ответ zerkms в С++
int a[] = { 1,2,3,4,3,1,2 };
int i = std::accumulate(a, a + 7, 0, std::bit_xor<int>());
Ответ 6
Вы можете отсортировать массив, а затем найти первый элемент, у которого нет пары. Для этого потребуется несколько циклов для сортировки и цикл для нахождения одного элемента.
Но более простым методом было бы установить двойные ключи в ноль или значение, которое невозможно в текущем формате. Также зависит от языка программирования, так как вы не можете изменять типы ключей в С++, в отличие от С#.