Довольно скрытая функция - то, что можно определить переменные в, если условие и его объем еще охватят только по если, и блоки:
if(int * p = getPointer()) {
// do something
}
Некоторое использование макросов, что, например, для обеспечения некоторого "заблокированного" объема как это:
struct MutexLocker {
MutexLocker(Mutex&);
~MutexLocker();
operator bool() const { return false; }
private:
Mutex &m;
};
#define locked(mutex) if(MutexLocker const& lock = MutexLocker(mutex)) {} else
void someCriticalPath() {
locked(myLocker) { /* ... */ }
}
Также BOOST_FOREACH использует его под капотом. Для завершения этого это не только возможно в если, но также и в переключателе:
switch(int value = getIt()) {
// ...
}
и в некоторое время цикле:
while(SomeThing t = getSomeThing()) {
// ...
}
(и также в для условия). Но я не слишком уверен, являются ли они всем этим полезным:)
Найдите самый маленький и самый большой элемент в списке. Разница наименьшая-наибольшая будет минимальной.
Если вы ищете неотрицательную разницу, тогда это, конечно, по крайней мере так же сложно, как проверить, есть ли в массиве два одинаковых элемента. Это называется проблемой уникальности элементов , и без каких-либо дополнительных предположений (например, ограничение размера целых чисел, допускающих другие операции, кроме сравнения) требуется> = n log n времени. Это одномерный случай поиска ближайшей пары точек .
Я думаю, что это возможно. Секрет в том, что на самом деле вам не нужно сортировать список, вам просто нужно создать список существующих чисел. Это может считаться "предположением" с алгоритмической точки зрения, но не с практической точки зрения. Мы знаем, что целые числа ограничены минимальным и максимальным значением.
Итак, создайте массив из 2-битных элементов, по 1 паре для каждого целого числа от INT_MIN до INT_MAX включительно, установите для всех их значение 00.
Итерируйте через весь список номеров. Для каждого числа в списке, если соответствующие 2 бита равны 00, установите их на 01. Если они 01, установите их на 10. В противном случае игнорируйте. Очевидно, это O (n).
Затем, если какой-либо из двух битов установлен в 10, это ваш ответ. Минимальное расстояние равно 0, потому что список содержит повторяющееся число. Если не, Просмотрите список и найдите минимальное расстояние. Многие люди уже указали, что для этого существуют простые алгоритмы O (n).
Итак, O (n) + O (n) = O (n).
Изменить: отвечать на комментарии.
Интересные моменты . Я думаю, что вы могли бы достичь тех же результатов, не делая никаких предположений, сначала найдя min / max списка и используя разреженный массив от min до max для хранения данных. Учитывает предположение INT_MIN / MAX, пространственную сложность и временную сложность O (m) сканирования массива.
Я думаю, что вы могли бы достичь тех же результатов, не делая никаких предположений, сначала найдя минимальное / максимальное значение списка и используя разреженный массив в диапазоне от min до max для хранения данных. Учитывает предположение INT_MIN / MAX, пространственную сложность и временную сложность O (m) сканирования массива. Я думаю, что вы могли бы достичь тех же результатов, не делая никаких предположений, сначала найдя min / max списка и используя разреженный массив от min до max для хранения данных. Учитывает предположение INT_MIN / MAX, пространственную сложность и временную сложность O (m) сканирования массива.Лучшее, что я могу придумать, - это отсортировать массив (возможно, комбинируя равные значения), а затем выполнить отсортированные сравнения - сортировка по ячейкам равна O (n + M ) (M - количество различных значений). Однако это требует больших объемов памяти. Некоторая форма сортировки по ведру или основанию системы счисления будет промежуточной по времени и более эффективной в пространстве.
Отсортируйте список с помощью radixsort (т.е. O (n) для целых чисел), затем итерация и отслеживание наименьшего расстояния до сих пор.
(Я предполагаю, что ваше целое число является типом с фиксированным битом. Если они могут содержать сколь угодно большие математические целые числа, radixsort будет O (n log n) также.)
Нет, не без предположений о числах / упорядочивании.
Это было бы возможно, учитывая отсортированный список.
Кажется, возможно отсортировать неограниченный набор целых чисел за время O (n * sqrt (log (log (n)))). После сортировки, конечно тривиально найти минимальную разницу в линейном времени.
Но я не могу придумать никакого алгоритма, чтобы сделать это быстрее, чем этот.
Я думаю, что ответ отрицательный, и доказательство похоже на доказательство того, что вы не можете сортировать быстрее, чем n lg n: вам нужно сравнить все элементы, т.е. создать дерево сравнения, что подразумевает алгоритм омега (n lg n).
EDIT . Хорошо, если вы действительно хотите поспорить, тогда вопрос не говорит о том, должна ли это быть машина Тьюринга или нет. С помощью квантовых компьютеров вы можете делать это за линейное время :)
Я не думаю, что вы сможете это сделать за O (n). Лучшее, что я могу придумать, это отсортировать их (что составляет O (n * log n)) и найти минимальную разницу между соседними парами в отсортированном списке (что добавляет еще O (n)).