Друг задал мне эту проблему как вызов, и я попытался найти такую проблему на LeetCode, но, к сожалению, не смог.
Вопрос
Учитывая В строке людей, пронумерованных от 1 до N, и в списке пар из M врагов найдите общее количество подстрок с людьми, в которых нет двух человек, являющихся врагами.
Пример: N = 5, enemies = [[3,4], [3,5]]
Ответ: 9
Пояснение: Эти непрерывные подынтервалы:
[1,1], [2,2], [3,3], [1,2], [2,3], [1,3], [4,4], [4,5], [5,5]
Мой подход
Мы определяем неконфликтный интервал как непрерывный интервал от (включительно) [a,b]
, где в этом интервале нет двух врагов.
Работа в обратном направлении, если я знаю, что существует неконфликтный интервал от [1,3]
, как в приведенном выше примере, я знаю, что количество смежных интервалов между этими двумя числами равно n(n+1)/2
, где n
- длина интервала. В этом случае длина интервала составляет 3
, поэтому существует 6
интервалов между (включительно) [1,3]
, которые считаются.
Расширение этого logi c, если у меня есть список все неконфликтующие интервалы , тогда ответ будет просто суммой (n_i*(n_i+1))/2
для каждой длины интервала n_i
.
Тогда все, что мне нужно сделать, это найти эти интервалы. Вот где я застрял.
Я не могу придумать подобную проблему программирования. Это похоже, но противоположно тому, о чем просит проблема Merge Interval в leetcode. В этой задаче нам вроде как даны хорошие интервалы и просят их объединить. Здесь нам плохо.
Есть какие-нибудь указания?
РЕДАКТИРОВАТЬ: Лучшее, что я мог придумать:
Это работает?
Итак, давайте определим max_enemy[i]
как самого большого врага, который меньше определенного person i
, где i
- это обычный [1,N]
. Мы можем сгенерировать это значение за O(M)
время, просто используя следующий l oop:
max_enemy = [-1] * (N+1) # -1 means it doesn't exist
for e1, e2 in enms:
e1, e2 = min(e1,e2), max(e1, e2)
max_enemy[e2] = max(max_enemy[e2], e1)
Затем, если мы go через массив человека, сохраняя скользящее окно. Скользящее окно закрывается, как только мы находим человека i
, у которого есть: max_enemy[i] < i
. Таким образом, мы знаем, что включение этого человека нарушит наш непрерывный интервал. Итак, теперь мы знаем, что наш интервал равен [s, i-1]
, и можем проводить вычисления. Сбрасываем s=i
и продолжаем.
Вот визуализация того, как это работает визуально. Мы рисуем путь между любыми двумя врагами:
N=5, enemies = [[3,4], [3,5]]
1 2 3 4 5
| | |
-----
| |
--------
EDIT2: Я знаю, что это не работает для N=5, enemies=[[1,4][3,5]]
, в настоящее время работает над исправлением, все еще застрял