二维数组

  1. 一个二维数组,每一行从左到右递增, 每一列从上到下递增。判断数组中是否含有该整数。
  2. 求二维子数组和的最大值(任意维度子矩阵,固定维度2×2子矩阵)。
  3. 矩阵原地转置(n×n方阵,m×n矩阵)。

1、思路:(详细参考:http://justjavac.iteye.com/blog/1310178

  剑指offer中提供的时间复杂度是O(m+n),如果考虑将线性二分查找的思想用在矩阵二分查找中,速度可能会有提升。

  

  假设查找17,第一次比较10,然后比较25,然后比较13,返回元素13,这时候再递归查找13左下角的矩阵和右上角的矩阵就可以了(红色椭圆部分);如果是查找9,第一次比较10,然后比较4,然后比较6,返回元素6,这时候递归查找6左下角的矩阵和右上角矩阵(绿色椭圆部分)。

 1 int binsearch(int value, int *a, int n, int m1, int n1, int m2, int n2)
 2 {
 3     int begin_m1 = m1, begin_n1 = n1, end_m2 = m2, end_n2 = n2;
 4     int left_result = 0,  right_result = 0;
 5     int i = (m1+m2)/2, j = (n1+n2)/2;
 6     if (a == NULL)
 7         return 0;
 8     if (value < *(a+m1*n+n1) || value > *(a+m2*n+n2))
 9         return 0;
10     else if (value == *(a+m1*n+n1) || value == *(a+m2*n+n2))
11         return 1;
12 
13     while ((i!=m1 || j!=n1) && (i!=m2 || j!=n2)){
14         if ( value == *(a+i*n+j) )
15             return 1;
16         else if ( value < *(a+i*n+j) ){
17             m2 = i;
18             n2 = j;
19             i = (i+m1)/2;
20             j = (j+n1)/2;
21         }
22         else{
23             m1 = i;
24             n1 = j;
25             i = (i+m2)/2;
26             j = (j+n2)/2;
27         }
28     }
29       
30     //search left & right
31     if ( i<end_m2 )
32         left_result = binsearch(value, a, n, i+1, begin_n1, end_m2, j);
33     if ( j<end_n2 )
34         right_result = binsearch(value, a, n, begin_m1, j+1, i, end_n2);
35     if (left_result | right_result )
36         return 1;
37     else
38         return 0;
39 }

 

2、思路:

  任意维度子矩阵:如果我们将连续k行的元素纵向相加,并对相加后所得的数列求连续最大和,则此连续最大和就是一个行数为k的最优子矩阵!

 1 #include <iostream>
 2 
 3 int RowSum(int matrix[][5], int m, int n, int col)
 4 {
 5     int total = 0, k;
 6     for (k = m; k <= n; k++)
 7         total += matrix[k][col];
 8     return total;
 9 }
10 
11 int MaxMatrixSum(int matrix[][5], int rows, int cols)
12 {
13     int maxSum = 0x80000000;
14     int curSum, rowSum;
15     int ele, i, j, col;
16 
17     for (i = 0; i < rows; i++)
18     {
19         for (j = i; j < rows; j++)
20         {
21             curSum = RowSum(matrix, i, j, 0);
22             rowSum = RowSum(matrix, i, j, 0);
23             for (col = 1; col < cols; col++)
24             {
25                 ele = RowSum(matrix, i, j, col);
26                 if (curSum < 0)
27                     curSum = ele;
28                 else
29                     curSum += ele;
30                 if (curSum > rowSum)
31                     rowSum = curSum;
32             }
33             if (rowSum > maxSum)
34                 maxSum = rowSum;
35         }                    
36     }
37     return maxSum;
38 }
39 
40 int main()
41 {
42     int matrix[][5] = {{1, -2, 0, 3, -4}, {2, -3, 4, -5, 1}, {1, -1, 5, 3, 0}};
43     int result = MaxMatrixSum(matrix, 3, 5);
44     printf("result: %d", result);
45 }

  固定维度子矩阵:

 1 int GetMaxMatrix(int** matrix, int& row, int& col) 
 2 { 
 3     int rowNum, colNum; 
 4 
 5     int sum=-(1<<31), temp = 0; 
 6 
 7     for (int i = 0; i < row - 1; i++) 
 8     { 
 9         for (int j = 0; j < col - 1; j++) 
10         { 
11             temp += (matrix[i][j] + matrix[i][j+1]);  
12             temp += (matrix[i+1][j] + matrix[i+1][j+1]); 
13 
14             if (temp > sum) 
15             { 
16                 sum = temp; 
17                 rowNum = i; 
18                 colNum = j; 
19             } 
20             temp = 0; 
21         } 
22     } 
23     row=rowNum; 
24     col=colNum; 
25 
26     return sum; 
27 } 

 

3、思路:

  方阵请参考:http://blog.csdn.net/friendan/article/details/8821591

 1 void Transpose(int arr[ROW][COL])  
 2 {  
 3     int temp;  
 4     for (int i=0;i<ROW;i++)  
 5     {  
 6         for(int j=i;j<COL;j++)  
 7         {  
 8             temp=arr[i][j];  
 9             arr[i][j]=arr[j][i];  
10             arr[j][i]=temp;  
11         }  
12     }  
13 }  

  矩阵请参考:http://www.qushichao.com/archives/47.html

  m×n矩阵用一维数组表示,关键是找到下标数字的移动环。一维数组中的下标移动可以通过二维数组的转置规则求得。

 1 void transpose(int *a, int m, int n){
 2    int flag = (m > n) ? n : m;
 3    for(int i = 1; i < flag; i++){
 4        int tmp = a[i];
 5        int position = i;
 6        while(true){
 7            int row = position / m;
 8            int column = position % m;
 9            int posToMove = column * n + row;
10            if(posToMove == i){
11                a[position] = tmp;
12                break;
13            }
14 
15            a[position] = a[posToMove];
16            position = posToMove;
17        }
18    }
19 }

 

posted on 2013-05-17 14:50  月moon鸟  阅读(186)  评论(0编辑  收藏  举报

导航