欢迎光临散文网 会员登陆 & 注册

最大加号标志

2022-11-10 11:30 作者:限量版范儿  | 我要投稿

题目

在一个 n x n 的矩阵 grid 中,除了在数组 mines 中给出的元素为 0,其他每个元素都为 1。mines[i] = [xi, yi]表示 grid[xi][yi] == 0

返回  grid 中包含 1 的最大的 轴对齐 加号标志的阶数 。如果未找到加号标志,则返回 0 。

一个 k 阶由 1 组成的 “轴对称”加号标志 具有中心网格 grid[r][c] == 1 ,以及4个从中心向上、向下、向左、向右延伸,长度为 k-1,由 1 组成的臂。注意,只有加号标志的所有网格要求为 1 ,别的网格可能为 0 也可能为 1 。


示例 1:

输入: n = 5, mines = [[4, 2]]
输出: 2
解释: 在上面的网格中,最大加号标志的阶只能是2。一个标志已在图中标出。
示例 2:

输入: n = 1, mines = [[0, 0]]
输出: 0
解释: 没有加号标志,返回 0 。

提示:

1 <= n <= 500
1 <= mines.length <= 5000
0 <= xi, yi < n
每一对 (xi, yi) 都 不重复

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/largest-plus-sign
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

暴力破解

  • 超时

  • 解题思路
    遍历所有点,取所有点的长度,取最大长度

public static int orderOfLargestPlusSign0(int n, int[][] mines) {        HashSet<Point> mineSet= new HashSet<>();        for (int i = 0; i < mines.length; i++) {            Point point =new Point();            point.x=mines[i][0];            point.y=mines[i][1];            mineSet.add(point);        }        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                Point center= new Point();                center.x=i;                center.y=j;                if(mineSet.contains(center))                {                    System.out.print(0+"\t");                }                else                {                    System.out.print(1+"\t");                }            }            System.out.println();        }        int maxLen=0;        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                Point center= new Point();                center.x=i;                center.y=j;                if(mineSet.contains(center))                {                    continue;                }                List<Point> allPoint = getAllPoint(n, center,mineSet);                int len = allPoint.size()/4+1;                maxLen=Math.max(len,maxLen);            }        }        return maxLen;    }    public static List<Point> getAllPoint(int n,Point center,HashSet<Point> mineSet)    {        List<Point> rs = new ArrayList<>();        rs.add(center);        int up  = center.x-1;        int right = center.y+1;        int down = center.x+1;        int left =center.y-1;       while (up>=0 && right<n&& down<n && left>=0) {           Point upPoint= new Point();           upPoint.x=up;           upPoint.y=center.y;           Point rightPoint= new Point();           rightPoint.x=center.x;           rightPoint.y=right;           Point downPoint= new Point();           downPoint.x=down;           downPoint.y=center.y;           Point leftPoint= new Point();           leftPoint.x=center.x;           leftPoint.y=left;           if(mineSet.contains(upPoint) ||                   mineSet.contains(rightPoint) ||           mineSet.contains(downPoint) ||           mineSet.contains(leftPoint))           {               break;           }           rs.add(upPoint);           rs.add(rightPoint);           rs.add(downPoint);           rs.add(leftPoint);           up--;           right++;           down++;           left--;       }        return rs;    }    public static class Point    {        public Integer x;        public Integer y;        @Override        public boolean equals(Object obj) {            return (this.x==((Point) obj).x) && (this.y==((Point) obj).y);        }        @Override        public int hashCode() {            return x.hashCode()+y.hashCode();        }    }

优化枚举

  • 可以通过

  • 解题思路
    设置一个map,将排除点标记为1,然后枚举所有点的长度,取最大长度,将上一个方法的哈希和实体转为简单的数组了。可以通过了

public static int orderOfLargestPlusSign(int n, int[][] mines) {        //初始化map值为0的矩阵        int[][] map= new int[n][n];        //        for (int i = 0; i < mines.length; i++) {            map[mines[i][0]][mines[i][1]]=1;        }        int maxLen=0;        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                if(map[i][j]==1)                {                    continue;                }                int len = getLen(n,i,j,map);                maxLen=Math.max(len,maxLen);            }        }        return maxLen;    }    public static int getLen(int n,int x,int y,int[][] map)    {        int up  = x-1;        int right = y+1;        int down = x+1;        int left =y-1;        int len=1;        while (up>=0 && right<n&& down<n && left>=0) {            if (map[up][y] == 1 ||                    map[x][right] == 1 ||                    map[down][y] == 1 ||                    map[x][left] == 1) {                break;            }            up--;            right++;            down++;            left--;            len++;        }        return len;    }

动态规划

  • 解题思路
    每个点所能形成的大加好标志。可以理解为四个方向连续的1的个数。并且是四个方法连续1个数的最小值。所以可以设置dp[][],为每个点为最大连续个数,然后取四个方向的最小值。以下代码还可以优化简写,但简写了之后,不太好理解,为了保证可读性,所以就没有在简写了。

public static int orderOfLargestPlusSign3(int n, int[][] mines) {        int[][] dp = new int[n][n];        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                dp[i][j]=n;            }        }        for (int i = 0; i < mines.length; i++) {            dp[mines[i][0]][mines[i][1]]=0;        }        for (int i = 0; i < n; i++) {            int left=0;            for (int j = 0; j < n; j++) {                left = dp[i][j]>0?left+1:0;                dp[i][j]=Math.min(dp[i][j],left);            }        }        for (int i = 0; i < n; i++) {            int right=0;            for (int j = n-1; j>=0; j--) {                right = dp[i][j]>0?right+1:0;                dp[i][j]=Math.min(dp[i][j],right);            }        }        for (int i = 0; i < n; i++) {            int up = 0;//循环up,x轴            for (int j = 0; j < n; j++) {                up = dp[j][i] > 0 ? up + 1 : 0;                dp[j][i] = Math.min(dp[j][i], up);            }        }        for (int i = 0; i < n; i++) {            int down = 0;            for (int j = n - 1; j >= 0; j--) {                down = dp[j][i] > 0 ? down + 1 : 0;                dp[j][i] = Math.min(dp[j][i], down);            }        }        int rs = 0;        for (int[] e : dp) {            rs = Math.max(rs, Arrays.stream(e).max().getAsInt());        }        return rs;    }

链接:https://www.dianjilingqu.com/607166.html

最大加号标志的评论 (共 条)

分享到微博请遵守国家法律