最大矩形问题【python实现】

问题描述

给定一个仅包含 01 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:

img

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。

示例 2:

输入:matrix = []
输出:0

示例 3:

输入:matrix = [["0"]]
输出:0

示例 4:

输入:matrix = [["1"]]
输出:1

示例 5:

输入:matrix = [["0","0"]]
输出:0

实现方式

先找到所有1的坐标,此坐标作为种子,分别向右/向下寻找连续的1,若找到,则宽/高+1,找到最大的宽高后

判断此宽高下的矩形,是否为全1矩阵,若是,则找到矩形并计算面积存入变量,若不是,则根据宽高大小回溯宽/高(优先回溯数值较大的)

这样每次减少的子矩阵元素是相对少的,可以确保找到当前种子下的最大矩形,找到后,和当前变量内存储的面积进行比较

若更大,则存入变量,否则继续下一个种子点的寻找,直至对所有种子搜索完成,变量内存储为最大矩形面积。

import numpy as np


def oneId(matrix): # 获取1的坐标
    oneid = []
    matrix = matrix
    print(matrix)
    height, width = len(matrix), len(matrix[0])
    for rowid, row in enumerate(matrix):
        for colid, num in enumerate(row):
            if num == 1:
                oneid.append([rowid, colid])
                # print([rowid,colid])
    return oneid


def recTangle(seed): # 以种子为左上角,搜索最大矩形
    h, w = 1, 1
    p = [seed[0], seed[1]]
    while p[1] + 1 <= len(matrix[0]) - 1 and matrix[p[0], p[1] + 1] == 1:
        w += 1
        p[1] += 1
    q = [seed[0], seed[1]]
    while q[0] + 1 <= len(matrix) - 1 and matrix[q[0] + 1, q[1]] == 1:
        h += 1
        q[0] += 1
    while ((matrix[seed[0]:seed[0] + h, seed[1]:seed[1] + w]) == 0).any():
        if h >= w:
            h -= 1
        if h < w:
            w -= 1
    square = matrix[seed[0]:seed[0] + h, seed[1]:seed[1] + w]
    # print(h, w, '\n', square)
    # print((square == 1).all())
    # print("--" * 30)
    return w * h


matrix = np.random.randint(0, 2, size=(10, 10))
# print([seed for seed in oneId(matrix)])
oneid = oneId(matrix)
maxarea = 0
for seed in oneid:
    area = recTangle(seed)
    if area > maxarea:
        maxarea = area

print(maxarea)

result

[[0 0 0 1 0 1 0 1 0 0]
 [1 1 0 1 0 1 0 1 1 0]
 [1 1 0 0 1 0 1 0 1 0]
 [1 1 0 0 0 0 0 0 0 0]
 [0 0 0 1 0 0 1 1 0 0]
 [1 0 1 1 1 1 0 1 0 0]
 [0 1 0 1 0 0 1 0 0 0]
 [0 0 1 0 0 1 1 0 0 0]
 [0 0 1 0 0 0 1 0 1 1]
 [0 1 1 1 0 0 0 1 0 1]]
6
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值