美文网首页
面试题 17.23. 最大黑方阵

面试题 17.23. 最大黑方阵

作者: 蓝笔头 | 来源:发表于2021-08-10 19:40 被阅读0次

题目地址

https://leetcode-cn.com/problems/max-black-square-lcci/

题目描述

给定一个方阵,其中每个单元(像素)非黑即白。设计一个算法,找出 4 条边皆为黑色像素的最大子方阵。

返回一个数组 [r, c, size] ,其中 r, c 分别代表子方阵左上角的行号和列号,size 是子方阵的边长。若有多个满足条件的子方阵,返回 r 最小的,若 r 相同,返回 c 最小的子方阵。若无满足条件的子方阵,返回空数组。

示例 1:

输入:
[
   [1,0,1],
   [0,0,1],
   [0,0,1]
]
输出: [1,0,2]
解释: 输入中 0 代表黑色,1 代表白色,标粗的元素即为满足条件的最大子方阵
示例 2:

输入:
[
   [0,1,1],
   [1,0,1],
   [1,1,0]
]
输出: [0,0,1]
提示:

matrix.length == matrix[0].length <= 200

题解

暴力枚举

class Solution {
    public int[] findSquare(int[][] matrix) {
        int length = matrix.length;
        int resultR = 0, resultC = 0, resultSize = 0;

        for (int r = 0; r < length; ++ r) {
            for (int c = 0; c < length; ++ c) {
                int maxSize = Math.min(length - r, length - c);
                for (int size = maxSize; size >= 1; -- size) {
                    if (isMatrix(matrix, r, c, size)) {
                        if (size > resultSize) {
                            resultR = r;
                            resultC = c;
                            resultSize = size;
                        }
                        break;
                    }
                }
            }
        }

        // 没有一个黑方阵的情况下要返回空数组
        if (resultSize == 0) {
            return new int[]{};
        }

        return new int[]{resultR, resultC, resultSize};
    }

    public boolean isMatrix(int[][] matrix, int r, int c, int size) {
        int rr = r + size - 1;
        int cc = c + size - 1;

        // 上下左右四条边
        
        // 遍历上面和上面的两条边
        for (int i = c; i <= cc; ++ i) {
            // 上面的边
            if (matrix[r][i] == 1) {
                return false;
            }
            // 下面的边
            if (matrix[rr][i] == 1) {
                return false;
            }
        }

        // 遍历左边和右边的两条边
        for (int i = r; i <= rr; ++ i) {
            // 左边的边
            if (matrix[i][c] == 1) {
                return false;
            }
            // 右边的边
            if (matrix[i][cc] == 1) {
                return false;
            }
        }

        return true;
    }
}

时间复杂度为:O(n^4),n 为原矩阵的边长。

上面遍历矩阵顶点和 size 的操作是必需的。

可以看看怎么优化 isMatrix() 的逻辑,通过预处理可以在常量时间判断 (r, c, size) 是否是一个矩阵。

预处理

class Solution {
    public int[] findSquare(int[][] matrix) {
        int length = matrix.length;
        int resultR = 0, resultC = 0, resultSize = 0;

        int[][] minBottomAndRight = buildMinBottomAndRight(matrix);
        int[][] minUpAndLeft = buildMinTopAndLeft(matrix);

        for (int r = 0; r < length; ++ r) {
            for (int c = 0; c < length; ++ c) {
                int maxSize = minBottomAndRight[r][c];
                for (int size = maxSize; size >= 1; -- size) {
                    int rr = r + size - 1;
                    int cc = c + size - 1;
                    boolean isMatrix = minUpAndLeft[rr][cc] >= size;
                    if (isMatrix) {
                        if (size > resultSize) {
                            resultR = r;
                            resultC = c;
                            resultSize = size;
                        }
                        break;
                    }
                }
            }
        }

        if (resultSize == 0) {
            return new int[]{};
        }

        return new int[]{resultR, resultC, resultSize};
    }

    public int[][] buildMinBottomAndRight(int[][] matrix) {
        int length = matrix.length;
        int[][] bottomAndRight = new int[length][length];
        for (int r = 0; r < length; ++ r) {
            for (int c = 0; c < length; ++ c) {
                // 计算下面的边有多少连续的黑色
                int bottom = 0;
                for (int rr = r; rr < length; ++ rr) {
                    if (matrix[rr][c] == 1) {
                        break;
                    }
                    bottom ++;
                }

                // 计算右边有多少连续的黑色
                int right = 0;
                for (int cc = c; cc < length; ++ cc) {
                    if (matrix[r][cc] == 1) {
                        break;
                    }
                    right ++;
                }

                bottomAndRight[r][c] = Math.min(bottom, right);
            }
        }
        return bottomAndRight;
    }

    public int[][] buildMinTopAndLeft(int[][] matrix) {
        int length = matrix.length;
        int[][] upAndLeft = new int[length][length];
        for (int r = 0; r < length; ++ r) {
            for (int c = 0; c < length; ++ c) {
                // 计算上面的边有多少连续的黑色
                int up = 0;
                for (int rr = r; rr >= 0; -- rr) {
                    if (matrix[rr][c] == 1) {
                        break;
                    }
                    up ++;
                }

                // 计算左边有多少连续的黑色
                int left = 0;
                for (int cc = c; cc >= 0; -- cc) {
                    if (matrix[r][cc] == 1) {
                        break;
                    }
                    left ++;
                }

                upAndLeft[r][c] = Math.min(up, left);
            }
        }
        return upAndLeft;
    }
}

时间复杂度为:O(n^3),n 为原矩阵的边长。
空间复杂度为:O(n^2),n 为原矩阵的边长。

参考

相关文章

  • 面试题 17.23. 最大黑方阵

    给定一个方阵,其中每个单元(像素)非黑即白。设计一个算法,找出 4 条边皆为黑色像素的最大子方阵。 返回一个数组 ...

  • 面试题 17.23. 最大黑方阵

    题目地址 https://leetcode-cn.com/problems/max-black-square-lc...

  • 寻找最大子方阵

    题目描述 给定一个元素为0或1的方阵,编写一个程序,找出其中最大的子方阵,使得该子方阵的元素都是1。程序先提示用户...

  • 构建数组

    网上的tx面试题:输入n,输出方阵:n=5时如下: n=3时如下: 代码: output:

  • Python3 欧拉计划 问题11-15

    11、数字方阵中的最大乘积   在下面20×20的数字方阵中,以第7行第9列的数字26[加粗]开始,右下对角线方向...

  • 《方阵》

    文/陈雄辉 我踟蹰在这方阵里 承受着钢筋水泥的凝固和冰冷 没有一种思路像炊烟一样柔软 没有一种表达像乡愁一样自然 ...

  • 方阵

    白云、丛兰、诗香、菩提、碧漪…… 收获、小窗、眉长、汤河、细雨 甲虫、她她、寒秋、安然、旖旎 枫红、南飞、月明、频...

  • 运动会(原文)

    11月10日星期五,我们学校举行了运动会。 先是走方阵,鲜花方阵,红旗方阵,然后是几个班级的方阵。我在走方阵时忘了...

  • 2019-07-23 MPPT

    mppt是什么? Maximum Power Point Tracking,最大功率点跟踪,指对光伏方阵表面温度变...

  • 3-16方阵问题

    从植树问题,我们扩展到了方阵的问题。 方阵问题是很重要的数形结合应用。 方阵有实心和空心两种,实心方阵暂时放下,那...

网友评论

      本文标题:面试题 17.23. 最大黑方阵

      本文链接:https://www.haomeiwen.com/subject/snjfbltx.html