You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻找矩阵中最大的全相同数字正方形子矩阵技术咨询

嘿,咱们一起把这个问题搞定!你现在的动态规划逻辑有个关键问题,没法正确识别由相同数字组成的最大正方形子矩阵。咱们一步步拆解修正:

问题分析

你的原代码的状态转移逻辑存在偏差——它错误地通过比较dp值的大小来决定当前dp[i,j],但实际上,要形成以(i,j)为右下角的相同数字正方形,需要依赖左上、上方、左方三个位置dp值的最小值再加1。只有这三个方向的正方形都能扩展到当前位置,才能确保形成更大的、全相同数字的正方形。

另外,原代码没有跟踪最大正方形的位置和边长,就算dp数组计算正确,也没法直接定位到你想要的3x3子矩阵。

修正后的C#代码
using System;

class Program
{
    static void Main()
    {
        int[,] a = {
            {7, 4, 7, 7, 7, 7},
            {7, 4, 7, 7, 7, 7},
            {7, 7, 1, 7, 7, 7},
            {7, 7, 3, 7, 9, 7},
            {1, 1, 7, 7, 1, 7},
            {7, 7, 7, 5, 7, 7}
        };

        int rows = a.GetLength(0);
        int cols = a.GetLength(1);
        int[,] dp = new int[rows, cols];
        int maxSide = 1;
        int maxRow = 0, maxCol = 0; // 记录最大正方形的右下角位置

        // 初始化第一行和第一列:单个元素本身就是1x1的正方形
        for (int i = 0; i < rows; i++)
        {
            dp[i, 0] = 1;
        }
        for (int j = 0; j < cols; j++)
        {
            dp[0, j] = 1;
        }

        // 填充dp数组并跟踪最大正方形
        for (int i = 1; i < rows; i++)
        {
            for (int j = 1; j < cols; j++)
            {
                // 只有当前元素与左上、上、左的元素完全相同时,才可能扩展正方形
                if (a[i, j] == a[i-1, j] && a[i, j] == a[i, j-1] && a[i, j] == a[i-1, j-1])
                {
                    // 取三个方向dp值的最小值加1,确保扩展后的正方形全为相同数字
                    dp[i, j] = Math.Min(Math.Min(dp[i-1, j], dp[i, j-1]), dp[i-1, j-1]) + 1;
                    // 更新最大正方形的信息
                    if (dp[i, j] > maxSide)
                    {
                        maxSide = dp[i, j];
                        maxRow = i;
                        maxCol = j;
                    }
                }
                else
                {
                    dp[i, j] = 1; // 无法扩展时,单个元素是最小的正方形
                }
            }
        }

        // 输出结果
        Console.WriteLine($"最大相同数字正方形的边长为: {maxSide}");
        Console.WriteLine($"它的左上角位置为: ({maxRow - maxSide + 1}, {maxCol - maxSide + 1})");
        Console.WriteLine("对应的子矩阵是:");
        for (int i = maxRow - maxSide + 1; i <= maxRow; i++)
        {
            for (int j = maxCol - maxSide + 1; j <= maxCol; j++)
            {
                Console.Write($"{a[i, j]} ");
            }
            Console.WriteLine();
        }
    }
}
代码关键说明
  1. DP数组定义:dp[i,j]表示以矩阵第i行第j列元素为右下角的、由相同数字组成的最大正方形的边长。
  2. 初始化逻辑:第一行和第一列的元素本身就是1x1的正方形,所以dp值统一设为1。
  3. 状态转移核心:当当前元素与左上、上方、左方元素完全相同时,取三个位置dp值的最小值加1——这保证了扩展后的正方形所有元素都是相同数字,因为这三个dp值对应的正方形本身就由该数字组成。
  4. 最大正方形跟踪:在填充dp数组时实时更新最大边长和右下角位置,最后通过右下角位置和边长反推出左上角位置,直接输出目标子矩阵。
运行结果

运行这段代码后,会精准输出你期望的右上角3x3的7组成的子矩阵:

最大相同数字正方形的边长为: 3
它的左上角位置为: (0, 3)
对应的子矩阵是:
7 7 7 
7 7 7 
7 7 7 

内容的提问来源于stack exchange,提问作者E.Snieckus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:30:32