2013-06-30 6 views
6

Учитывая несортированный набор A, что является наиболее эффективным решением для нахождения наименьшего целого числа x, которое не является элементом A такой, что x потребности быть больше некоторого целого m?найти наименьшее целое число, которое не является в массиве

например.

Вход: A = {7, 3, 4, 1}, m = 5

Выход: x = 6

Я ищу решение в C, но любой вид псевдокоде будет полезно ... Может быть решена эта проблема в О (п) где n - заданный размер?

ответ

5

Я решил использовать его и добавить массив. Здесь «len» - длина массива.

int findMin(int *arr,int n,int len) 
{ 
    int *hash; 
      if(len==0) 
       {return -1; //fail 
       } 
    hash=(int*)calloc(len,sizeof(int)); //hash function I'm using is f(x)=f(x)-n; 
    int i; 
    for(i=0;i<len;i++){ 
     if(arr[i]>n && arr[i]<len+n){ //because max element can't be more than n 
      hash[arr[i]-n]++; 
     } 
    } 

    i=1; 
    while(i<len){ 
     if(hash[i]==0) 
      return len+i; 
     i++; 
    } 
      return len+n+1; 
} 

Порядок этой души - это время работы O (n) и O (n).

+3

'calloc (0, len);' кажется немного маленьким. – wildplasser

+0

@wildplasser Спасибо за указание. Я обновил ответ – banarun

+0

'Если nmemb или size равно 0, то calloc() возвращает либо NULL, либо уникальное значение указателя, которое впоследствии может быть успешным - , дословно переданное в free().' – wildplasser

3

Следующий код Java должен работать для вас:

public static int findMinNotInArray(int array[], int n) { 
    int frequency[] = new int[array.length]; 

    if (n < max(array)) { 
     for (int i = 0; i < array.length; i++) { 
      if (array[i] > n && array[i] < n + array.length) 
       frequency[array[i] - (n + 1)]++; 
     } 

     for (int i = 0; i < frequency.length; i++) { 
      if (frequency[i] == 0) 
       return i + n + 1; 
     } 
     return -1; 
    } else { 
     return n + 1; 
    } 
} 

public static int max(int array[]) { 
    int max = array[0]; 
    for (int i = 1; i < array.length; i++) { 
     if (array[i] > max) { 
      max = array[i]; 
     } 
    } 
    return max; 
} 

Приведенный выше код просто отслеживает число от n+1 к (n+1) + lengthOfA ли какой-либо один из этого диапазона присутствует в массиве или нет! И возвращает первый неподходящий номер!

+1

Nope; для тестового примера OP это возвращает '-1' вместо (правильного)' 6'. – michaelb958

+0

Я отредактировал ответ, пожалуйста, просмотрите! –

1

Я думаю, что наиболее целесообразным подходом является сортировка массива в первую очередь. Затем вы можете выполнить двоичный поиск для m, а затем линейный поиск следующего пункта, где соседи более одного раза.

Сложность этого подхода заключается в том, что алгоритм сортировки, а именно O (nlogn), в большинстве случаев.

+1

Зачем вам сортировать его первым? Вы можете просто перебирать один раз над массивом, создать (if (a [i] pivot) min_so_far = a [i])? Thats take O (n), вам нужно идти один раз над массивом, вот и все. Сортировка - O (n log n), что больше. – SinisterMJ

+0

Вы должны принять во внимание, что есть очевидный пробел, который заполняется только позже. Например: {0, 2, 3, 4, 1} и m = 0. Вы должны вернуть 5 в этом случае, и вы не хотите последовательно использовать 1, 2, 3, 4, потому что это будет означать O (n * n). Вот почему я сначала сортирую. – cmaster

+1

@AntonRoth: вам нужно найти значение, которое * не * в массиве. Ваш подход будет работать для нахождения значения, которое находится в массиве. – interjay

Смежные вопросы