2026-01-18-LeetCode刷题笔记-1895-最大的幻方

题目信息

  • 平台:LeetCode
  • 题目:1895. 最大的幻方
  • 难度:中等
  • 题目链接:Largest Magic Square

题目描述

给定一个 m×n 的整数矩阵,找出其中最大的"幻方"边长。幻方要求:子矩阵的每一行、每一列以及两条对角线的和都相等。


初步思路

  1. 直接枚举所有正方形并逐行逐列求和会很慢。
  2. 用行前缀、列前缀和两条对角线前缀和,把任意行/列/对角线的和在 O(1) 内算出来。
  3. 从大到小枚举边长 k,找到第一个满足条件的子矩阵即可返回。

算法分析

  • 核心:四类前缀和(行/列/主对角线/副对角线)+ 从大到小枚举边长。
  • 技巧:主对角线用 (i,j) 累加到 (i+1,j+1),副对角线用 (i,j) 累加到 (i+1,j-1)。
  • 时间复杂度:O(mnmin(m,n)^2)
  • 空间复杂度:O(m*n)

正确性简述

前缀和保证能在 O(1) 内得到任意行、列、对角线的和。对于固定的 k×k 子矩阵,我们验证两条对角线和为 s,再验证 k 行与 k 列的和均为 s,即可判定为幻方。按 k 从大到小枚举,第一次找到的 k 即为最大幻方边长。


代码实现(C++)

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    int largestMagicSquare(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        vector<vector<int>> row(m, vector<int>(n + 1, 0));
        vector<vector<int>> col(m + 1, vector<int>(n, 0));
        vector<vector<int>> diag(m + 1, vector<int>(n + 1, 0));
        vector<vector<int>> anti(m + 1, vector<int>(n + 1, 0));

        for (int i = 0; i < m; ++i) {
            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];
                diag[i + 1][j + 1] = diag[i][j] + grid[i][j];
                anti[i + 1][j] = anti[i][j + 1] + grid[i][j];
            }
        }

        int maxK = min(m, n);
        for (int k = maxK; k >= 1; --k) {
            for (int i = k; i <= m; ++i) {
                for (int j = k; j <= n; ++j) {
                    int s = diag[i][j] - diag[i - k][j - k];
                    if (anti[i][j - k] - anti[i - k][j] != s) continue;
                    bool ok = true;
                    for (int r = i - k; r < i && ok; ++r) {
                        if (row[r][j] - row[r][j - k] != s) ok = false;
                    }
                    for (int c = j - k; c < j && ok; ++c) {
                        if (col[i][c] - col[i - k][c] != s) ok = false;
                    }
                    if (ok) return k;
                }
            }
        }
        return 1;
    }
};

测试用例

输入 输出 说明
[[7,1,4,5,6],[2,5,1,6,4],[1,5,4,3,2],[1,2,7,3,4]] 3 存在 3×3 幻方
[[5,1,3,1],[9,3,3,1],[1,3,3,8]] 2 最大幻方边长为 2
[[1,2],[3,4]] 1 无更大幻方,返回 1

总结与反思

  1. 幻方判定可拆为"行列与对角线和相等",前缀和大幅减少重复计算。
  2. 先枚举更大的边长能尽早返回,避免无意义的细粒度搜索。
相关推荐
代码小书生19 小时前
math,一个基础的 Python 库!
人工智能·python·算法
AI科技星19 小时前
全域数学·数术本源·高维代数卷(72分册)【乖乖数学】
人工智能·算法·数学建模·数据挖掘·量子计算
生成论实验室19 小时前
《事件关系阴阳博弈动力学:识势应势之道》第一篇:生成正在发生——从《即事经》到事件-关系网络
人工智能·科技·算法·架构·创业创新
漂流瓶jz19 小时前
UVA-1152 和为0的4个值 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·二分查找·题解·aoapc·算法竞赛入门经典·uva
leoufung19 小时前
LeetCode 76:Minimum Window Substring 题解与滑动窗口思维详解
算法·leetcode·职场和发展
其实防守也摸鱼19 小时前
CTF密码学综合教学指南--第四章
网络·笔记·安全·网络安全·密码学·ctf
小O的算法实验室19 小时前
2026年IEEE TETCI,山区环境下基于双种群进化的协同无人机巡逻任务协同优化,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
生成论实验室20 小时前
《事件关系阴阳博弈动力学:识势应势之道》第二篇:阴阳博弈——认知的动力学基础
数据结构·人工智能·科技·神经网络·算法
风筝在晴天搁浅20 小时前
字节高频题 小于n的最大数
算法
LabVIEW开发20 小时前
LabVIEW水力机组空蚀在线监测
算法·labview·labview知识·labview功能·labview程序