[CTCI] 最大子方阵

最大子方阵

题目描述

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

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

测试样例:
[[1,1,1],[1,0,1],[1,1,1]],3
返回:3

 

要看清题目,题目说的是四条边同一种颜色,不是四条边都是1。想法就是记录每个点右侧与下侧的连续0或1的个数,这样在给定一个左上角坐标与边长时,可以以O(1)的时间判断是否构成矩形。总的时候复杂度为O(N^3)。

 1 class SubMatrix {
 2 public:
 3     struct cell {
 4         int right, down;
 5         cell() : right(0), down(0){}
 6     };
 7     int maxSubMatrix(vector<vector<int> > mat, int n) {
 8         // write code here
 9         vector<vector<cell>> mmat1(n, vector<cell>(n));
10         vector<vector<cell>> mmat2(n, vector<cell>(n));
11         int tmp1, tmp2, res;
12         for (int i = n - 1; i >= 0; --i) {
13             for (int j = n - 1; j >= 0; --j) {
14                 if (j == n - 1) tmp1 = tmp2 = 0;
15                 else tmp1 = mmat1[i][j+1].right, tmp2 = mmat2[i][j+1].right;
16                 if (mat[i][j] == 1) mmat1[i][j].right = tmp1 + 1;
17                 else mmat2[i][j].right = tmp2 + 1;
18                 if (i == n - 1) tmp1 = tmp2 = 0;
19                 else tmp1 = mmat1[i+1][j].down, tmp2 = mmat2[i+1][j].down;
20                 if (mat[i][j] == 1) mmat1[i][j].down = tmp1 + 1;
21                 else mmat2[i][j].down = tmp2 + 1;
22             }
23         }
24         for (int i = n; i > 0; --i) {
25             if (isOK(mmat1, n, i) || isOK(mmat2, n, i)) return i;
26         }
27         return 0;
28     }
29     bool isOK(vector<vector<cell>> &mat, int n, int size) {
30         for (int i = 0; i <= n - size; ++i) {
31             for (int j = 0; j <= n - size; ++j) {
32                 if (isSquare(mat, i, j, size)) return true;
33             }
34         }
35         return false;
36     }
37     bool isSquare(vector<vector<cell>> &mat, int x, int y, int size) {
38         cell &lefttop = mat[x][y], &leftdown = mat[x+size-1][y], &righttop = mat[x][y+size-1];
39         if (lefttop.right < size) return false;
40         if (lefttop.down < size) return false;
41         if (leftdown.right < size) return false;
42         if (righttop.down < size) return false;
43         return true;
44     }
45 };

 

posted @ 2015-07-30 21:27  Eason Liu  阅读(830)  评论(0编辑  收藏  举报