子矩阵中共享1的最长对角线

来源:

http://www.careercup.com/question?id=6130581557477376

 

Given a n by m matrix of bits find the largest X that is formed in the matrix and return the size of the diagonal of that X. An X is defined as 2 equally sized diagonals that share a single 1. 

For instance, the matrix: 

00100001 
00010010 
00001100 
00001100 
00010010 
00100001 

Will return a size of 1, because the given X is invalid as the middle part does not share a single 1. On the other hand, the following matrix 

101 
010 
101 

Will return a value of 3, as the diagonal is 3. Write such program,

pretonesio on September 02, 2013 in United States for Powerpoint Report Duplicate | Flag 

 

 

思路:

At every cell, there are two diagonals that pass through this cell, one going from top-left corner of the matrix to bottom-right corner and the other going from top-right to bottom-left corner. The idea is to keep a matrix of the same size as the input matrix, each entry represents the the number of consecutive ones in the diagonal going from top-left to bottom-right corner such that the sequence of ones starts at the top left of current cell and ends at the current cell, similarly we keep 3 other matrices, one for sequences of ones in the diagonal going from top-left to bottom-right but starting at a cell that is at the bottom right of the current cell. The other 2 matrices are kept from the other diagonal going from top-right to bottom-left corner. 
for example, consider the matrix: 
0 1 1 1 0 0 0 
0 1 0 0 0 0 0 
0 1 1 0 1 0 1 
1 0 0 1 1 1 0 
1 0 1 1 0 1 0 
1 1 1 1 1 0 1 

top-left matrix keeping counts of ones starting at top left and ending at each cell: 
0 1 1 1 0 0 0 
0 1 0 0 0 0 0 
0 1 2 0 1 0 1 
1 0 0 3 1 2 0 
1 0 1 1 0 2 0 
1 2 1 2 2 0 3 

bottom-left 
0 1 2 1 0 0 0 
0 1 0 0 0 0 0 
0 2 1 0 4 0 2 
1 0 0 3 3 1 0 
1 0 2 2 0 2 0 
1 1 1 1 1 0 1 

top-right 
0 1 1 1 0 0 0 
0 2 0 0 0 0 0 
0 1 1 0 1 0 1 
2 0 0 2 1 2 0 
1 0 3 2 0 1 0 
1 4 3 1 2 0 1 

bottom-right 
0 1 1 1 0 0 0 
0 3 0 0 0 0 0 
0 1 2 0 2 0 1 
1 0 0 1 3 1 0 
2 0 2 2 0 2 0 
1 1 1 1 1 0 1 

and then at each cell[i,j] in the original matrix, get length of sequences of ones ending at the 4 neighboring diagonal cells from the matrices computed above, namely [i-1, j-1], [i-1, j+1], [i+1, j-1], [i+1, j+1], compute "minValue" which is the minimum of these values. 
size of an X with center at the current cell is 2*minValue+1. 
time complexity O(n*m), space Complexity O(n*m).

代码:

#include <iostream>


using namespace std;


int findGreatestX(bool **matrix, int m, int n) {
    int **topLeft = new int*[m];
    for (int i = 0; i < m; i++)
        topLeft[i] = new int[n];

    int **topRight = new int*[m];
    for (int i = 0; i < m; i++)
        topRight[i] = new int[n];

    int **botLeft = new int*[m];
    for (int i = 0; i < m; i++)
        botLeft[i] = new int[n];

    int **botRight = new int*[m];
    for (int i = 0; i < m; i++)
        botRight[i] = new int[n];

    // Calculating topLeft
    for (int i = 0; i < m; i++)
        topLeft[i][0] = matrix[i][0];

    for (int i = 0; i < n; i++)
        topLeft[0][i] = matrix[0][i];

    for (int i = 1; i < m; i++)
        for (int j = 1; j < n; j++)
            topLeft[i][j] = (matrix[i][j]) ? topLeft[i-1][j-1] + 1 : 0;
    
    // Calculating topRight
    for (int i = 0; i < m; i++)
        topRight[i][n-1] = matrix[i][n-1];

    for (int i = 0; i < n; i++)
        topRight[0][i] = matrix[0][i];

    for (int i = 1; i < m; i++)
        for (int j = n-2; j >= 0; j--)
            topRight[i][j] = (matrix[i][j]) ? topRight[i-1][j+1] + 1 : 0;

    // Calculating botLeft
    for (int i = 0; i < m; i++)
        botLeft[i][0] = matrix[i][0];

    for (int i = 0; i < n; i++)
        botLeft[m-1][i] = matrix[m-1][i];

    for (int i = m-2; i >= 0; i--)
        for (int j = 1; j < n; j++)
            botLeft[i][j] = (matrix[i][j]) ? botLeft[i+1][j-1] + 1 : 0;


    // Calculating botRight
    for (int i = 0; i < m; i++)
        botRight[i][n-1] = matrix[i][n-1];

    for (int i = 0; i < n; i++)
        botRight[m-1][i] = matrix[m-1][i];

    for (int i = m-2; i >= 0; i--)
        for (int j = n-2; j >= 0; j--)
            botRight[i][j] = (matrix[i][j]) ? botRight[i+1][j+1] + 1 : 0;


    int maxMinVal = 0;
    int curMinVal;

    for (int i = 1; i < m-1; i++) {
        for (int j = 1; j < n-1; j++) {
            curMinVal = min(min(botRight[i+1][j+1],
                                botLeft[i+1][j-1]),
                            min(topRight[i-1][j+1],
                                topLeft[i-1][j-1]));
            if (curMinVal > maxMinVal)
                maxMinVal = curMinVal;
        }
    }
    //delete
    for (int i = 0; i < m; i++)
    {
        delete[] topLeft[i];
        delete[] topRight[i];
        delete[] botLeft[i];
        delete[] botRight[i];
    }
    delete[] topLeft;
    delete[] topRight;
    delete[] botLeft;
    delete[] botRight;
    
    return (2*maxMinVal) + 1;
} 

int main()
{  
    
    bool **test = new bool*[3];
    for(int i=0; i<3; i++)
        test[i] = new bool[3];
    
    bool a[6][7] =   {{0,1,1,1,0,0,0},
                      {0,1,0,0,0,0,0},
                      {0,1,1,0,1,0,1},
                      {1,0,0,1,1,1,0},
                      {1,0,1,1,0,1,0},
                      {1,1,1,1,1,0,1}};
    bool b[3][3] = {{1,0,1},
                    {0,1,0},
                    {1,0,1}};
    
    for(int i=0; i<3; i++)
    {
        for(int j=0; j<3; j++)
            test[i][j] = b[i][j];
    }

    cout<<findGreatestX(test,3,3)<<endl;

    for(int m=0; m<3; m++)
        delete[] test[m];
    delete[] test;
    system("pause");
}

 

 

posted on 2013-10-07 17:21  walkwalkwalk  阅读(328)  评论(0编辑  收藏  举报

导航