zoukankan      html  css  js  c++  java
  • 算法——二维数组中寻找边界最长的正方形边框(不包括内部)

    给定一个方阵,其中每个单元(像素)非黑即白。设计一个算法,找出 4 条边皆为黑色像素的最大子方阵。
    返回一个数组 [r, c, size] ,其中 r, c 分别代表子方阵左上角的行号和列号,size 是子方阵的边长。若有多个满足条件的子方阵,返回 r 最小的,若 r 相同,返回 c 最小的子方阵。若无满足条件的子方阵,返回空数组。
    leetcode

    解题思路:这道题和之前遇到的寻找最大正方形很类似,不同的是,这里只需要一个边框就行了,所以更加麻烦一些。

    • 首先通过DP计算以每个元素为起点,向下的和向右的最大边长;
    • 然后枚举所有点,计算最大正方形;
    • 枚举一个点的时候,再比较枚举另外两条边,这样就能获得一个最大的正方形。
    class Solution {
        public int[] findSquare(int[][] matrix) {
            int n = matrix.length;
            if(n == 0) return new int[0];
            int m = matrix[0].length;
    
            int[][] row = new int[n + 1][m + 1];
            int[][] col = new int[n + 1][m + 1];
            int[] res = new int[3];
    
    		// 计算每个点向下和向右的最大边长,从最后开始
            for(int i = n - 1; i >= 0; i--) {
                for(int j = m - 1; j >= 0; j--) {
                    if(matrix[i][j] == 1) continue;
    
                    row[i][j] = row[i][j + 1] + 1;
                    col[i][j] = col[i + 1][j] + 1;
                }
            }
    
    		// 枚举每个点的最大正方形
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < m; j++) {
                	// 获取以该点为顶底的可能的最大正方形边长
                    int cur = Math.min(col[i][j], row[i][j]);
    				// 小于当前答案,那就没必要再枚举了
                    if(cur < res[2]) continue;
    				// 再去从大到小枚举边长,是否能够成正方形
                    for(int x = cur; x > 0; x--) {
                    	// 查看对应的点的边长是否符合要求
                        if(Math.min(row[i + x - 1][j], col[i][j + x - 1]) >= x) {
                            if(res[2] < x) {
                            	// 更新答案
                                res = new int[]{i, j, x};
                            }
                            // 已经枚举到最大的边长了,就没必要再枚举小的了
                            break;
                        }
                    }
                }
            }
    
            return res[2] == 0 ? new int [0] : res;
        }
    }
    
  • 相关阅读:
    MySQL 幻读详解
    vue-layer 弹窗z-index问题
    vue-cli 路径不变 改变参数 显示不同组件
    mysql ---- limit使用方式
    mysql ---- 官网的测试数据库
    2020年度总结和2021年目标
    校招(春招实习 + 秋招)总结感想
    Centos8和7的区别(参照redhat)
    centos8 网卡命令(centos7也可用)
    排查linux系统是否被入侵
  • 原文地址:https://www.cnblogs.com/lippon/p/14117615.html
Copyright © 2011-2022 走看看