请设计一个高效算法,找到四条边颜色相同的最大子方阵。

有一个方阵,其中每个单元(像素)非黑即白(非0即1),请设计一个高效算法,找到四条边颜色相同的最大子方阵。

给定一个01方阵mat,同时给定方阵的边长n,请返回最大子方阵的边长。保证方阵边长小于等于100。

测试样例:

[[1,1,1],[1,0,1],[1,1,1]],3
返回:3

 


  int maxSubMatrix(vector<vector<int> > mat, int n)   
    {  
        // write code here  
        //选定最大子方阵的边长,选择顶点,判断是合法  
        int maxlength=n;  
        while(maxlength)  //选择边长  
        {  
            for(int i=0;i<=n-maxlength;i++)  
            {  
                for(int j=0;j<=n-maxlength;j++)  
                {  
                    //当前顶点为[i,j];  
                    int key=mat[i][j];  
                    //判断是否合法  
                    bool flag=true;  
                    for(int k=0;k<maxlength;k++)  
                    {  
                        int k1=mat[i][j+k];  
                        int k2=mat[i+maxlength-1][j+k];  
                        int k3=mat[i+k][j];  
                        int k4=mat[i+k][j+maxlength-1];  
                        if(k1!=key||k2!=key||k3!=key||k4!=key)  
                        {  
                            flag=false;  
                            break;  
                        }  
                    }  
                    if(flag)  
                        return maxlength;  
                }  
            }  
            maxlength--;  
        }  
        return 0;  
    }

 

扩展:

给定一个由0,1组成的n*n方阵(n在运行时提醒用户输入),判断其中由全1组成的最大子方阵的左上角位置和阶数。例如用户输入n为5,随机产生的方阵如下:

程序的输出为:最大子方阵位于(2,2),阶数3。

要求编写方法实现上述功能,返回值是一个包含3个元素的数组,依次表示行下标,列下标,阶数。

方法原型:public static int[] findLargestBlock(int[][] m)

                                             

 

public class MaxSubMatrix {  
    public static void main(String[] args) {  
        Scanner input=new Scanner(System.in);  
        System.out.println("请输入方阵维数n:");  
        int n=input.nextInt();  
        int [][] m=new int[n][n];  
        int []a=new int[3];  
        //产生一个n*n矩阵,元素为0或1并输出  
        for(int i=0;i<n;i++){  
            for(int j=0;j<n;j++){  
                m[i][j]=(int)(Math.random()*10)%2;        
                System.out.print(m[i][j]+"\t");  
            }  
            System.out.print("\n");  
        }  
        a=findLargestBlock(m);  
        System.out.print("\n");  
        System.out.println("最大子方阵位于:("+a[0]+","+a[1]+")");  
        System.out.println("阶数:"+a[2]);  
    }  
    //找到最大的全为1的矩阵块  
    public  static int[] findLargestBlock(int [][] m){  
        boolean t=true;  
        int []a=new int[3];  
        int n=m.length;  
        int i=0,j=0,l=0;  
        for(l=n;l>=1;l--){ //矩阵维数,从最大开始 

for(i=0;i<=n-l;i++){  
                for(j=0;j<=n-l;j++){  
                    t=true;  
                    for(int x=i;x<i+l;x++){  
                        for(int y=j;y<j+l;y++){  
                            if(m[x][y]!=1){    //不为1退出此轮循环  
                                t=false;  
                                break;  
                            }  
                        }  
                        if(t==false) break;  
                    }  
                    if(t==true) break;  
                }  
                if(t==true) break;  
            }  
            if(t==true) break;  
        }  
        a[0]=i;  
        a[1]=j;  
        a[2]=l;  
        return a;  
    }   

转载于:https://my.oschina.net/u/2822116/blog/795776

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值