У меня есть программа, которая получает запросы (массив строк размером n) из разных доменов (каждое входное значение называется доменом) каждую секунду i.
В течение 5 секунд для данного домена программа должна принять не более 2 успешных запросов.
Также максимум 5 успешных запросов за 30 секунд.
Для каждого запроса программа должна возвращать либо «успех», если он принят, либо «ошибку», если он не принят.
Пример:
n = 9, requests = ["xyz", "abc", "xyz", "pqr", "abc", "xyz", "xyz", "abc", "xyz"]
Result =
["success", "success", "success", "success", "success", "success", "error", "success", "success"]
Объяснение:
domain xyz occurs at indices = [0,2,5,6,8]
domain abc = [1,4,7]
domain pqr = [3]
Если мы выберем индекс 6, если мы выберем диапазон 5 секунд, будет два успешных запроса с индексом 2 и 5, поэтому мы получим ответ об ошибке с индексом 6. В остальных случаях мы получаем успешный ответ.
Ограничения
n range is 1 to 10^4
input string contains lowercase English letters.
Вот что я попробовал:
public static List<String> solve(List<String> requests) {
List<String> result = new ArrayList<>();
Map<String, List<Integer>> map = new HashMap<>();
int n = requests.size();
for(int i=0; i<n; i++) {
String s = requests.get(i);
int time = i;
// remove items older than 30 seconds
while(!map.getOrDefault(s, new ArrayList<>()).isEmpty() && time - map.get(s).get(0) >= 30) {
map.get(s).remove(0);
}
// remove items older than 5 seconds
while(!map.getOrDefault(s, new ArrayList<>()).isEmpty() && time - map.get(s).get(0) >= 5) {
map.get(s).remove(0);
}
//check if we have 2 successful requests for given domain
if (map.getOrDefault(s, new ArrayList<>()).size() >= 2) {
map.get(s).remove(0);
result.add("error");
} else {
result.add("success");
map.computeIfAbsent(s, k-> new ArrayList<>()).add(time);
}
}
return result;
}
Когда я пытался решить эту проблему, моя программа не выдавала неправильный результат во многих тестовых случаях. Каков правильный подход к решению этой проблемы.
@ wLui155, первый цикл while предназначен для проверки ограничения по времени в 30 секунд, у меня есть второй цикл while для проверки ограничения по времени в 5 секунд. Следующее условие if для двух успешных запросов




Вы ничего не проверяете после первого цикла while, на самом деле вы можете просто пропустить его и получить тот же результат, он все равно не делает абсолютно ничего, чего не делает следующий цикл while. Второй цикл while приводит к отбрасыванию всех значений, не входящих в диапазон 5 с, поэтому невозможно проверить условие 30 с.
Исправлен код (также используется LinkedList вместо ArrayList, где он используется как очередь, которая сдвигает все элементы в ArrayList каждый раз, когда вы удаляете голову).
public static List<String> solve(List<String> requests) {
List<String> result = new ArrayList<>(requests.size()); // you know capacity
Map<String, LinkedList<Integer>> map = new HashMap<>();
int n = requests.size();
for(int = 0; i < n; i++) {
String s = requests.get(i);
int time = i;
// remove items older than 30 seconds only
// no unnecessary list creations
while(map.containsKey(s) && !map.get(s).isEmpty()) && time - map.get(s).getFirst() >= 30) {
map.get(s).removeFirst();
}
// add element, you also need it in error case for next iteration
map.computeIfAbsent(s, k-> new LinkedList<>()).add(time);
// check both conditions now
// the 2nd part is the general way to test if more than x elements in y time
int m = map.get(s).size();
if (m > 5 || m > 2 && time - map.get(s).get(m - 3) < 5) {
result.add("error");
} else {
result.add("success");
}
}
return result;
}
` if (m > 5 || m > 2 && time - map.get(s).get(m - 3) < 5) {` можете ли вы объяснить больше об этой строке кода
@learner да. && имеет более высокий приоритет, поэтому он аналогичен m > 5 || (m > 2 && time - map.get(s).get(m - 3) < 5). Первая часть проверяет, есть ли более 5 элементов в течение 30 секунд (поскольку те, что снаружи, отбрасываются), вторая часть сначала проверяет, есть ли более 2 элементов, и если третий сзади находится в течение 5 секунд, то у нас есть 3 элемента в последние 5 секунд, потому что время заказано.
Похоже, ваш подход не обрабатывает случай, когда у вас меньше или равно двум успешным запросам в течение пяти секунд, но более пяти успешных запросов в течение тридцати секунд; например, определенный домен
dпоявляется время от времени[0, 5, 10, 15, 20], и вы рассматриваете запрос на него в период между20и30. Кроме того, отсутствие крайних случаев сбоя или программы драйвера немного усложняет отладку.