Прямоугольная область в массиве

учитывая матрицу N*N, имеющую 1 в 0 и заданное целое число k, каков наилучший метод для поиска прямоугольной области, такой, что в ней есть k 1 ???

2 ответов


рассмотрим эту более простую проблему:

учитывая вектор размера N, содержащий только значения 1 и 0, найдите подпоследовательность, содержащую ровно k значений 1 в нем.

пусть A заданный вектор и S[i] = A[1] + A[2] + A[3] + ... + A[i], что означает, сколько 1 в подпоследовательности A[1..i].

для каждого i мы заинтересованы в существовании j <= i такое, что S[i] - S[j-1] == k.

нет O(n) С a хэш-таблица, используя следующее соотношение:

S[i] - S[j-1] == k => S[j-1] = S[i] - k

let H = an empty hash table
for i = 1 to N do
  if H.Contains (S[i] - k) then your sequence ends at i
  else
    H.Add(S[i])

теперь мы можем использовать это для решения данной проблемы в O(N^3): для каждой последовательности строк в данной матрице (есть O(N^2) последовательности строк), рассмотрим эту последовательность для представления вектора и применим к ней предыдущий алгоритм. Вычисление S немного сложнее в случае матрицы, но это не так сложно понять. Дайте мне знать, если вам нужно больше подробности.

обновление: Вот как алгоритм будет работать на следующей матрице, предполагая k = 12:

0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0

рассмотрим только первую строку:

0 1 1 1 1 0

считайте, что это вектор 0 1 1 1 1 0 и применяем алгоритм для более простой задачи на нем: мы обнаруживаем, что нет подпоследовательности, складывающейся до 12, поэтому мы двигаемся дальше.

рассмотрим первые две строки:

0 1 1 1 1 0
0 1 1 1 1 0

считать их вектором 0+0 1+1 1+1 1+1 1+1 0+0 = 0 2 2 2 2 0 и примените алгоритм для более простой задачи на нем: опять же, нет подпоследовательности, которая добавляет до 12, поэтому двигайтесь дальше.

рассмотрим первые три строки:

0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0

считайте их вектором 0 3 3 3 3 0 и применить алгоритм для более простой задачи на нем: мы находим последовательность, начинающуюся в позиции 2 и заканчивающуюся в позиции 5, чтобы быть решением. Из этого мы можем получить весь прямоугольник с помощью простой бухгалтерии.


Я могу сделать это с помощью O(N^3*log (N)), но уверен, что лучшее решение быстрее. Сначала вы создаете другую n * n матрицу B (начальная матрица-A). Логика B следующая:

B[i][j] - is the number of ones on rectangle in A with corners (0,0) and (i,j).

вы можете оценить B для O(n^2) динамическим программированием: B[i][j] = B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j].

теперь очень легко решить эту проблему с O (N^4), повторяя все правое дно (i=1..N, j=1..N, O (N^2)), слева внизу (z=1..j, O (N)), а справа-верхний (t=1..i, O (N)) и вы получаете количество единиц в этом прямоугольнике с помощью B:

sum_of_ones = B[i][j] - B[i][z-1] - B[t-1][j] + B[t-1][z-1].

Если вы получили точно k:k==sum_of_ones, то результат.

чтобы сделать это N^3*log (N), вы должны найти правый верхний двоичным поиском (так что не просто перебирать все возможные ячейки).