2013-10-27 3 views
4

Вопрос: Задано N целых чисел [N < = 10^5], посчитайте полные пары целых чисел, которые имеют разность K. [K> 0 и K < 1e9]. Каждое из N целых чисел будет больше 0 и, по крайней мере, K от 2^31-1 (все может быть выполнено с 32-битными целыми числами).Самый быстрый алгоритм для выбора пар чисел

1-я строка содержит N & K (целые числа). Вторая строка содержит N номеров набора. Все номера N гарантированы, чтобы быть отличным.

Теперь вопрос от hackerrank. У меня есть решение для вопроса, но оно не удовлетворяет предельному сроку для всех тестовых примеров. Я не уверен, можно ли использовать другой алгоритм, но у меня нет идей. Пойду, если кто-то потратит немного времени, чтобы проверить мой код и дать чаевые или два.

temp = input() 
temp = temp.split(" ") 
N = int(temp[0]) 
K = int(temp[1]) 
num_array = input() 
num_array = num_array.split(" ") 
diff = 0 
pairs= 0 
i = 0 
while(i < N): 
    num_array[i] = int(num_array[i]) 
    i += 1 
while(num_array != []):  
    j = 0 
    while(j < (len(num_array)-1)): 
     diff = abs(num_array[j+1] - num_array[0]) 
     if(diff == K): 
      pairs += 1 
     j += 1 
    del num_array[0] 
    if(len(num_array) == 1): 
     break 
print(pairs) 

ответ

5

Вы можете сделать это в приближенно минимаксного линейного времени с помощью следующей процедуры:

Таким образом, (п) Раствор O:

  1. Для каждого числа х добавить его в хэш-набор H [ х]
  2. для каждого числа х проверить ли хк в H, если да - добавить 1 ответить

или с помощью какой-то б alanced структура (например, дерево на основе набора) в O (nlgn)

Этого решения баз на предположении, что целые числа являются отчетливым, если они не нужно хранить число раз элемента было «добавлено в наборе "и вместо добавления 1, чтобы ответить - добавить продукт Н [х] * H [х + к]

Таким образом, в общем, вы берете некоторое HashMap H с„значение по умолчанию 0“

  1. для каждого номер x карта обновления: H [x] = H [x] +1
  2. Для каждого номера x добавить ответ H [x] * H [xk] (вы делаете не нужно проверять, находится ли он на карте, потому что, если это не так, H [xk] = 0)

и снова - решение с использованием хэш-карты O (n) и использование древовидной карты O (nlgn)

Так данный набор numbesr а, а число к (решение для различных чисел):

H=set() 
ans=0 
for a in A: 
    H.add(a) 
for a in A: 
    if a-k in H: 
    ans+=1 
print ans 

или короче

H=set(A) 
ans = sum(1 for a in A if a-k in H) 
print ans 
+0

Хорошо. Вопрос в том, есть ли у u заданный ряд значений, найдите общее число пар чисел с разностью k. Например. Если u имеет 5 чисел: 1 3 5 2 7 ... и k = 2, пары: (1,3) (3,5) (5,7). В моем случае я проверяю первое число (в примере выше, «1») на все остальные значения. Если разница существует, я добавляю 1 к окончательному answer.i, затем делаю то же самое для следующего значения (опустив ранее проверенное число). Можете ли вы объяснить свой путь немного лучше? –

+0

@Nwaiwu - здесь нечего объяснять - предлагаемый подход ismply проходит через каждый элемент и проверяет, существует ли какой-либо элемент с разницей 'k'. Весь «трюк» заключается в том, что эта проверка может выполняться в постоянное время (с использованием хэш-набора) вместо линейного времени (путем циклирования - как в вашем решении). – lejlot

+0

@lejlot: Большое спасибо. Это сработало :) . Еще одна вещь: то, что означало u, означает, что «можно делать в постоянное время (используя хэш-набор) вместо линейного времени (путем циклизации - как в вашем решении)». Я раньше не использовал set() в python, так как это быстрее? –

2

Используйте словарь (хэш-карту).

Шаг 1: Заполните словарь D всеми элементами массива. Шаг 2: Вводят слова всех A [i] + k в словаре.

Dictionary<int> dict = new Dictionary<int>(); 
foreach (int n in num_array) do dict.Add(n); 
int solitions = 0; 
foreach (int n in num_Array) do 
    if dict.contains(n+k) 
    solutions += 1; 

Заполнение словаря - O (1), поиск - O (1). Для каждого элемента массива это O (n). Это так быстро, как только можно.

Извините, но вы должны перевести его на python.

EDIT: та же идея, что и предыдущая. Извините, что разместите дубликат. Слишком поздно удалить мой дубликат, я думаю.

+0

вы можете ** всегда ** удалять свой собственный ответ – lejlot

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