每日微软面试题――day 8(最大的二维子矩阵) - 花心龟 cabin - 博客频道 - CSDN.NET
题:求一个矩阵中最大的二维子矩阵(元素和最大).如:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
中最大的是:
4 5
5 3
方法一、这是最容易想到也是最容易实现的方法。遍历矩阵(行迭代器为i,列迭代器为j),以当前遍历到的元素为首a[i,j],计算二维子矩阵的和(sum=a[i,j]+a[i+1,j]+a[i,j+1]+a[i+1,j+1]),并找出和最大的二维矩阵,注意矩阵的最后一行和最后一列不用遍历。时间复杂度为O(i*j)。
Read full article from 每日微软面试题――day 8(最大的二维子矩阵) - 花心龟 cabin - 博客频道 - CSDN.NET
题:求一个矩阵中最大的二维子矩阵(元素和最大).如:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
中最大的是:
4 5
5 3
一、增加一个变量,last_vsum(叫做“最新纵向和”,v是vertical) 且初始化为last_vsum = a[0,0]+a[1,0],其作用将在下面说明。
二、改变遍历方式,原先每次访问四个元素,现在变为每次访问纵向的两个元素(a[i,j],a[i+1,j]),横向遍历,遍历的起始点改为第二个元素,终点到最后一个元素。
三、改变求和方式,求和方法是:首先将上一次保存的和last_vsum加进sum中,再将last_vsum更新为当前纵向的两个元素a[i,j],a[i+1,j]之和,然后再将last_vsum加入sum中,这样就得到本次二维矩阵的和可与maxsum进行比较。如此每次求和只需访问两个元素a[i,j],a[i+1,j]。
void get_max_22Matrix(int *a,int row,int col,int *result) { int maxsum=0,result_i,result_j,sum,last_vsum=0; #define a(i,j) *(a+(i)*col+(j)) #define result(i,j) *(result+(i)*2+(j)) last_vsum = a(0,0)+a(1,0); //初始last_vsum for(int i=0; i<row-1; i++) { for(int j=1; j<col; j++) { sum = last_vsum ; //将last_vsum加入sum last_vsum = a(i,j)+a(i+1,j);//更新last_vsum sum += last_vsum;//将更新后的last_vsum再与sum累加,得到当前子二维矩阵的和 if(maxsum<sum) { maxsum = sum; result_i = i; result_j = j-1; } } } /* 将结果存储到result二维数组中*/ result(0,0)=a(result_i,result_j); result(1,0)=a(result_i+1,result_j); result(0,1)=a(result_i,result_j+1); result(1,1)=a(result_i+1,result_j+1); #undef a #undef result }
- public int[][] herizonalFind(int[][] a,int row,int col){
- int[][] result=new int[2][2];
- int lastHerizonalSum=a[0][0]+a[0][1];
- int sum=0;
- int p=0;
- int q=0;
- for(int i=1;i<row;i++){
- for(int j=0;j<col-1;j++){
- int temp=lastHerizonalSum+a[i][j]+a[i][j+1];
- lastHerizonalSum=a[i][j]+a[i][j+1];
- if(temp>sum){
- sum=temp;
- p=i;
- q=j;
- }
- }
- }
- result[0][0]=a[p-1][q];
- result[0][1]=a[p-1][q+1];
- result[1][0]=a[p][q];
- result[1][1]=a[p][q+1];
- return result;
- }
- public int[][] verticalFind(int[][] a,int row,int col){
- int[][] result=new int[2][2];
- int lastVerticalSum=a[0][0]+a[1][0];
- int sum=0;
- int p=0;
- int q=0;
- for(int i=0;i<row-1;i++){
- for(int j=1;j<col;j++){
- int temp=lastVerticalSum+a[i][j]+a[i+1][j];
- lastVerticalSum=a[i][j]+a[i+1][j];
- if(temp>sum){
- sum=temp;
- p=i;
- q=j;
- }
- }
- }
- result[0][0]=a[p][q-1];
- result[0][1]=a[p][q];
- result[1][0]=a[p+1][q-1];
- result[1][1]=a[p+1][q];
- return result;
- }
方法一、这是最容易想到也是最容易实现的方法。遍历矩阵(行迭代器为i,列迭代器为j),以当前遍历到的元素为首a[i,j],计算二维子矩阵的和(sum=a[i,j]+a[i+1,j]+a[i,j+1]+a[i+1,j+1]),并找出和最大的二维矩阵,注意矩阵的最后一行和最后一列不用遍历。时间复杂度为O(i*j)。
- public int[][] brutalFind(int[][] a){
- int[][] result=new int[2][2];
- int row=a.length;
- int col=a[0].length;
- int sum=0;
- int p=0;
- int q=0;
- for(int i=0;i<row-1;i++){
- for(int j=0;j<col-1;j++){
- int x=a[i][j];
- int y=a[i][j+1];
- int z=a[i+1][j];
- int k=a[i+1][j+1];
- int temp=x+y+z+k;
- if(temp>sum){
- sum=temp;
- p=i;
- q=j;
- }
- }
- }
- result[0][0]=a[p][q];
- result[0][1]=a[p][q+1];
- result[1][0]=a[p+1][q];
- result[1][1]=a[p+1][q+1];
- return result;
- }
Read full article from 每日微软面试题――day 8(最大的二维子矩阵) - 花心龟 cabin - 博客频道 - CSDN.NET