Разбор задачи: Максимальный прямоугольник

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

 def maximalRectangle(matrix):
    """
    Находит площадь наибольшего прямоугольника, содержащего только '1', в бинарной матрице.
    :param matrix: List[List[str]] - бинарная матрица, содержащая '0' и '1'
    :return: int - площадь наибольшего прямоугольника
    """
    if not matrix or not matrix[0]:
        return 0

    rows, cols = len(matrix), len(matrix[0])
    heights = [0] * cols
    max_area = 0

    def largestRectangleArea(heights):
        stack = []
        max_area = 0
        heights.append(0)  # Добавляем 0 в конец для упрощения обработки
        for i, h in enumerate(heights):
            while stack and heights[stack[-1]] > h:
                height = heights[stack.pop()]
                width = i if not stack else i - stack[-1] - 1
                max_area = max(max_area, height * width)
            stack.append(i)
        heights.pop()  # Убираем добавленный 0
        return max_area

    for row in matrix:
        for col in range(cols):
            heights[col] = heights[col] + 1 if row[col] == '1' else 0
        max_area = max(max_area, largestRectangleArea(heights))

    return max_area

1. Проверка на пустую матрицу

if not matrix or not matrix[0]:
    return 0

Первым делом мы проверяем, что матрица не пуста и что у нее есть хотя бы один столбец. Если матрица пуста, результатом будет 0, так как прямоугольников в пустой матрице нет.


2. Инициализация переменных

rows, cols = len(matrix), len(matrix[0])
heights = [0] * cols
max_area = 0
  • rows и cols — количество строк и столбцов в матрице.
  • heights — список, который будет использоваться для хранения высот непрерывных '1' в каждом столбце. Он инициализируется нулями.
  • max_area — переменная для хранения максимальной площади прямоугольника.

3. Вспомогательная функция largestRectangleArea

def largestRectangleArea(heights):
    stack = []
    max_area = 0
    heights.append(0)  # Добавляем 0 в конец для упрощения обработки
    for i, h in enumerate(heights):
        while stack and heights[stack[-1]] > h:
            height = heights[stack.pop()]
            width = i if not stack else i - stack[-1] - 1
            max_area = max(max_area, height * width)
        stack.append(i)
    heights.pop()  # Убираем добавленный 0
    return max_area

Эта функция принимает массив высот heights и возвращает площадь наибольшего прямоугольника, который можно построить на основе этих высот. Она работает следующим образом:

  1. Добавляем фиктивный нулевой элемент в конец списка, чтобы гарантировать обработку всех столбцов.
  2. Используем стек для хранения индексов столбцов. Это помогает отслеживать прямоугольники, которые можно построить.
  3. Если текущая высота меньше высоты, соответствующей верхнему индексу в стеке, мы "выгружаем" стек, вычисляя площадь возможного прямоугольника.
  4. В конце убираем добавленный нулевой элемент.

4. Основной цикл обработки строк матрицы

for row in matrix:
    for col in range(cols):
        heights[col] = heights[col] + 1 if row[col] == '1' else 0
    max_area = max(max_area, largestRectangleArea(heights))

Здесь мы обновляем массив heights для каждой строки матрицы:

  • Если текущая ячейка равна '1', увеличиваем соответствующую высоту.
  • Если текущая ячейка равна '0', высота сбрасывается в 0. После обновления высот вызываем функцию largestRectangleArea, чтобы найти максимальную площадь прямоугольника для текущего состояния heights. Полученный результат обновляет значение max_area.

5. Возврат результата

return max_area

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


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

Рассмотрим матрицу:

matrix = [["1", "0", "1", "0", "0"],
          ["1", "0", "1", "1", "1"],
          ["1", "1", "1", "1", "1"],
          ["1", "0", "0", "1", "0"]]
  1. На первой строке:

    heights = [1, 0, 1, 0, 0]
    

    После вызова largestRectangleArea максимальная площадь равна 1.

  2. На второй строке:

    heights = [2, 0, 2, 1, 1]
    

    После вызова largestRectangleArea максимальная площадь обновляется до 3.

  3. На третьей строке:

    heights = [3, 1, 3, 2, 2]
    

    После вызова largestRectangleArea максимальная площадь становится 6.

  4. На четвертой строке:

    heights = [4, 0, 0, 3, 0]
    

    Максимальная площадь остается равной 6.

Итог: максимальная площадь прямоугольника равна 6.


Основные моменты

  • Мы преобразуем каждую строку матрицы в массив высот.
  • Для каждого состояния высот вычисляем максимальную площадь прямоугольника с помощью вспомогательной функции largestRectangleArea.
  • Используем стек для эффективного вычисления площади прямоугольников.

Этот подход позволяет обработать матрицу строка за строкой и получить искомую площадь.

 



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