Разбор задачи: Количество недавних звонков

Предложенный нами код решения:

 from collections import deque

class RecentCounter(object):

    def __init__(self):
        """
        Инициализация:
        - Задайте структуру данных для хранения временных меток запросов.
        """
        # Используем deque для эффективной работы с очередью
        self.queue = deque()

    def ping(self, t):
        """
        Добавляет запрос с меткой времени t и возвращает количество запросов за последние 3000 миллисекунд.

        :type t: int
        :rtype: int
        """
        # Добавляем метку времени в очередь
        self.queue.append(t)

        # Удаляем старые запросы, которые находятся за пределами временного интервала [t - 3000, t]
        while self.queue[0] < t - 3000:
            self.queue.popleft()  # Удаляем элементы с начала очереди

        # Возвращаем количество оставшихся запросов
        return len(self.queue)

Задача заключается в том, чтобы реализовать класс RecentCounter, который отслеживает количество запросов, сделанных за последние 3000 миллисекунд. Каждый запрос имеет свою метку времени t, и нам нужно вернуть количество запросов, сделанных за период времени от t-3000 до t (включая текущий запрос).

1. Инициализация класса (__init__)

В конструкторе класса создается структура данных для хранения временных меток запросов. В данном случае используется очередь deque из библиотеки collections.

Почему deque?
Очередь, реализованная через deque, удобна тем, что позволяет эффективно добавлять элементы в конец и удалять элементы с начала. Это важно, потому что нам нужно поддерживать в очереди только те запросы, которые попадают в временной интервал от t-3000 до t.

self.queue = deque()

2. Метод ping

Метод ping принимает метку времени запроса и добавляет её в очередь. Затем происходит очистка очереди от старых запросов, метки времени которых меньше, чем t - 3000, чтобы оставить в очереди только те запросы, которые попадают в интервал [t-3000, t].

Шаги работы метода ping:

  1. Добавление текущего запроса в очередь: Каждый раз, когда вызывается метод ping, метка времени запроса t добавляется в конец очереди.

    self.queue.append(t)
    
  2. Удаление старых запросов из очереди: После добавления нового запроса необходимо удалить все старые запросы, которые не попадают в нужный временной интервал. Для этого из очереди удаляются элементы с начала, пока первый элемент очереди не станет таким, что его метка времени лежит в интервале [t-3000, t].

    while self.queue[0] < t - 3000:
        self.queue.popleft()
    
  3. Возврат количества запросов, попадающих в интервал: После того как старые запросы удалены, в очереди остаются только те, которые находятся в интервале [t-3000, t]. Количество таких запросов возвращается в виде длины очереди.

    return len(self.queue)
    

Пример работы:

  1. При первом вызове ping(1) в очереди будет только один запрос (метка времени 1), и метод вернет 1.
  2. При вызове ping(100) в очереди будет два запроса: 1 и 100, и метод вернет 2, так как оба запроса попадают в интервал [100-3000, 100].
  3. При вызове ping(3001) в очереди будут три запроса: 1, 100 и 3001. Интервал теперь будет [3001-3000, 3001], и метод вернет 3.

Почему решение работает корректно?

  • Очередь: Используя deque, мы эффективно управляем добавлением и удалением запросов. Запросы добавляются в конец очереди, а старые запросы удаляются с начала очереди. Это оптимизирует процесс подсчета актуальных запросов в интервале.
  • Простота: Каждая метка времени добавляется в очередь, а затем удаляются только те метки, которые не попадают в интервал, что делает решение простым и понятным.

Решение хорошо работает в условиях задачи, поскольку все операции по добавлению и удалению элементов происходят в предсказуемое время и без сложных вычислений.

 



Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии