Вопрос довольно старый, но ОП до сих пор не отправил его/ее ответ ...
Я попытаюсь объяснить людям, которые также наткнулись на этот вопрос.
Основная идея - использовать скользящее окно, ширина которого равна k. Наше внимание будет ограничено в этом окне, так что разница между i и j (индексами) в этом окне не может быть больше k. И мы проверяем наличие двух чисел в этом окне с разницей не более t. Если таких чисел, то мы закончили. В противном случае наше окно будет двигаться вперед на один шаг, и мы снова проверим.
Однако, используя ведра, мы можем сделать гораздо лучше!
Всякий раз, когда мы сталкиваемся с числом в окне, мы делим его на (t + 1).Предположим, что результат B, тогда мы поместим его в ведро [B].
Если t = 3, то цифры 0, 1, 2, 3 будут помещены в ведро [0], цифры 4, 5, 6, 7 будут помещены в ведро [1] и 8, 9, 10 , 11 будет помещен в ведро [2] и т. Д. Мы гарантировали, что все числа в одном ковше будут иметь разности, не превышающие t. И еще есть одно: 4 - 2 = 2 < 3 и они находятся в разных ведрах. Да, некоторые числа с разницей меньше t могут быть помещены в разные ковши. В таких случаях, однако, они могут находиться только в соседних ведрах.
Ниже приведен пример:
nums = [1, 5, 17, 6, 8], t = 2, k = 5
(. Мы не должны беспокоиться о к теперь, так как это то же самое, как длина Nums)
С т = 2, так что всякий раз, когда мы встречаем число в списке, мы делим его на t + 1 (целое число делится) и помещаем его в соответствующее ведро.
1/3 = 0 --> We put 1 in bucket[0]
5/3 = 1 --> We put 5 in bucket[1]
Поскольку может быть элементы в ведрах соседних ведра [1], удовлетворяющие требования, мы должны проверить эту. bucket [0] имеет номер 1, но 5 - 1> 3, а еще нет ведра [2], поэтому мы продолжаем.
17/3 = 5 --> We put 17 in bucket[5]
Нет ведра [4] или ковша [6], поэтому мы продолжаем.
6/3 = 2 --> We put 6 in bucket[2]
Мы должны проверить номер в ковше [1]: | 5 - 6 | = 1 < 2 поэтому есть такие числа, и мы возвращаем True.
Если мы поместим 8 в ведро [2], то найдем, что в нем уже есть элемент, который равен 6. Поскольку все элементы в одном ковше имеют разности, не большие, чем t, мы делаем.
Итак, чтобы проверить, есть ли два числа с разницей меньше t, мы помещаем каждое число, с которым мы сталкиваемся в ведре. Если в этом ковше уже есть элемент, мы закончили. В противном случае мы проверяем, имеет ли соседние ведра элемент, удовлетворяющий требованию, если этого не происходит, мы продолжаем помещать числа в ведро.
Мы почти закончили. Теперь нам нужно рассмотреть ширину окна k. После помещения всех k чисел в ведра, если мы не найдем два таких числа, нам нужно переместить окно на один шаг вперед. То есть, чтобы удалить самое левое число и соответствующее его ведро и добавить новый номер в его ведро. Если его ведро уже было принято, мы закончили. В противном случае мы проверяем его соседние ведра, если они есть.
Ниже приведен код Python.
if t < 0 or not nums or k <= 0:
return False
buckets = {}
width = t + 1
for n, i in enumerate(nums):
buck = i // width
if buck in buckets:
return True
else:
buckets[buck] = i
if buck - 1 in buckets and i - buckets[buck-1] <= t:
return True
if buck + 1 in buckets and buckets[buck+1] - i <= t:
return True
if n >= k:
del buckets[nums[n-k] // width]
return False
Привет! Спасибо за ответ. Верьте или нет, это был мой ответ на проблему. Это определенно работает, но LeetCode ищет немного более эффективное решение (т. Е.
cottonman