LeetCode——5202. 最大的幻方(Largest Magic Square)[中等]——分析及代码(Java)

本文详细解析了LeetCode第5202题《最大幻方》的解题思路和Java实现,采用前缀和与枚举相结合的方法,实现了在给定矩阵中寻找最大幻方的尺寸。代码执行效率高,空间和时间复杂度得到优化,通过计算行列前缀和来快速判断幻方条件。
摘要由CSDN通过智能技术生成

LeetCode——5202. 最大的幻方[Largest Magic Square][中等]——分析及代码[Java]

一、题目

一个 k x k 的 幻方 指的是一个 k x k 填满整数的方格阵,且每一行、每一列以及两条对角线的和 全部相等 。幻方中的整数 不需要互不相同 。显然,每个 1 x 1 的方格都是一个幻方。

给你一个 m x n 的整数矩阵 grid ,请你返回矩阵中 最大幻方 的 尺寸 (即边长 k)。

示例 1:

输入:grid = [[7,1,4,5,6],[2,5,1,6,4],[1,5,4,3,2],[1,2,7,3,4]]
输出:3
解释:最大幻方尺寸为 3 。
坐标(1,1)为左上角的正方形,每一行,每一列以及两条对角线的和都等于 12 。
- 每一行的和:5+1+6 = 5+4+3 = 2+7+3 = 12
- 每一列的和:5+5+2 = 1+4+7 = 6+3+3 = 12
- 对角线的和:5+4+3 = 6+4+2 = 12

示例 2:

输入:grid = [[5,1,3,1],[9,3,3,1],[1,3,3,8]]
输出:2

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • 1 <= grid[i][j] <= 10^6

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

二、分析及代码

1. 前缀和 + 枚举

(1)思路

从大到小枚举所有正方形,判断是否为幻方。可通过预计算各行、列的前缀和,降低时间复杂度。

(2)代码

class Solution {
    public int largestMagicSquare(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        
        //计算各行、各列的前缀和
        int[][] row = new int[m][n + 1], col = new int[m + 1][n];
        Arrays.fill(col[0], 0);
        for (int i = 0; i < m; i++) {
            row[i][0] = 0;
            for (int j = 0; j < n; j++) {
                row[i][j + 1] = row[i][j] + grid[i][j];
                col[i + 1][j] = col[i][j] + grid[i][j];
            }
        }                
        
        //从大到小枚举正方形
        for (int len = Math.min(m, n); len > 1; len--) {//枚举边长
            for (int i = 0; i + len <= m; i++) {//枚举起始点横坐标
                for (int j = 0; j + len <= n; j++) {//枚举起始点纵坐标
                    boolean isMagic = true;
                    int sum = row[i][j + len] - row[i][j], dia1 = 0, dia2 = 0;//选取第一行的和作为标准计算
                    for (int k = 0; k < len; k++) {
                        if (row[i + k][j + len] - row[i + k][j] != sum || col[i + len][j + k] - col[i][j + k] != sum) {//计算各行、列和是否相等
                            isMagic = false;
                            break;
                        }
                        dia1 += grid[i + k][j + k];//计算对角线和
                        dia2 += grid[i + len - 1 - k][j + k];//计算另一对角线和
                    }
                    if (isMagic == true && dia1 == sum && dia2 == sum)//判断行、列及对角线和是否全部相等
                        return len;
                }
            }
        }
        return 1;//边长为1的方格一定是幻方
    }
}

(3)结果

执行用时 :6 ms,在所有 Java 提交中击败了 100.00% 的用户;
内存消耗 :38 MB,在所有 Java 提交中击败了 100.00% 的用户。
(目前提交用户量不足,暂无排名)

三、其他

还可通过预计算对角线的前缀和,进一步简化算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值