最大的二階子矩陣

來源:互聯網
上載者:User

轉載自http://blog.csdn.net/zhanxinhang,作者:花心龜的扮演者ZhanHang


:求一個矩陣中最大的二維子矩陣(元素和最大).如:

          1 2 0 3 4
          2 3 4 5 1
          1 1 5 3 0
          中最大的是:  
          4 5
          5 3
          要求:(1)寫出演算法;(2)分析時間複雜度;(3)用C寫出關鍵代碼

分析方法一、這是最容易想到也是最容易實現的方法。遍曆矩陣(行迭代器為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)。

實現代碼:

    /**     Author:花心龜     Blog:http://blog.csdn.net/zhanxinhang     **/      void get_max_22Matrix(int *a,int row,int col,int *result)      //a為原矩陣,row,col指a矩陣的行和列,result儲存最終得到的子二維矩陣      {        int maxsum=0,result_i,result_j,sum;              #define a(i,j) *(a+(i)*col+(j))  //用二維的形式表示一維數組,訪問需要一定的代價      #define result(i,j) *(result+(i)*2+(j))                for(int i=0; i<row-1; i++)          for(int j=0; j<col-1; j++)            {              sum = a(i,j)+a(i+1,j)+a(i,j+1)+a(i+1,j+1); //訪問四個元素並相加得到當前的和              if(maxsum<sum) //更新最大子二維矩陣資料                {                  maxsum = sum;                  result_i = i;                  result_j = j;                }            }                /* 將結果儲存到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      }  


方法二、這是對方法一的改進。分析方法一可知,方法一在每次遍曆中,必須同時訪問四個元素(a[i,j],a[i+1,j],a[i,j+1],a[i+1,j+1]),方法一的遍曆效果(用方框框住的表示當前訪問到或已訪問的元素,元素被框住的次數就越多,表示被訪問的次數也就越多,被染的顏色也就越深)。

可看出,方法一中多個元素被重複訪問多次,要知道訪問一次元素的代價是不容小視的。實際上我們是可以對其進行改進,使每個元素的訪問次數儘可能的降低的。改進方法如下:

一、增加一個變數,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]。

方法二執行步驟與:

實現代碼:

    /**     Author:花心龜     Blog:http://blog.csdn.net/zhanxinhang     **/      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      }  


方法二與方法一效果對照圖:

其中,方法二有中間行需要被訪問兩次,總共訪問次數為5+5+2*5=20次。

而方法一3,4,5元素被訪問了4次,總共訪問次數為4+2*8+3*4=32次。

方法二與方法一的時間複雜度相同,但是效率要高於方法一,尤其是在大矩陣情況下效果尤為明顯

方法三、這可作為對方法二的補充。以上方法二中給的樣本矩陣是3*5的矩陣,也就是列大於行的矩陣,但如果是行大於列依然用方法2去執行效果如何呢?效果如所示:

5*3矩陣,訪問次數為6+2*9=24

可見當行大於列時,利用方法2效果已經下降,如果是大矩陣的話可不只只有4的相差啊

針對這種情況,只需對方法二稍作改正,沒錯,就是原先方法二是橫向遍曆,現在改為縱向遍曆,效果如所示:

同樣是5*3矩陣,訪問次數為5+5+2*5=20

又回到了方法2的訪問次數。

這樣如果是列大於行的矩陣使用方法二,也就是橫向遍曆

如果是行大於列的矩陣使用方法三,也就縱向遍曆

實現代碼略。

…………………………………………

贈一測試代碼:

int main()  {    int a[3*5]={1,2,0,3,4,            2,3,4,5,1,            1,1,5,3,0};    int result[2*2]={0};      get_max_22Matrix(a,3,5,result);     #define result(i,j) *(result+(i)*2+(j))     for(int i =0; i<2; i++)       {         for(int j=0; j<2; j++)       printf("%d ",result(i,j));         printf("\n");       }    return 0;  }  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.