zoukankan      html  css  js  c++  java
  • [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 };

     

  • 相关阅读:
    个人总结
    4号团队-团队任务3:每日立会(2018-12-07)
    4号团队-团队任务3:每日立会(2018-12-06)
    4号团队-团队任务3:每日立会(2018-12-05)
    团队任务3
    课后作业2
    课后作业1
    相识两年的自我介绍
    Android模拟器
    用户
  • 原文地址:https://www.cnblogs.com/easonliu/p/4690671.html
Copyright © 2011-2022 走看看