750. Number Of Corner Rectangles
问题描述:
Given a grid where each entry is only 0 or 1, find the number of corner rectangles.
A corner rectangle is 4 distinct 1s on the grid that form an axis-aligned rectangle. Note that only the corners need to have the value 1. Also, all four 1s used must be distinct.
Example 1:
Input: grid = [[1, 0, 0, 1, 0], [0, 0, 1, 0, 1], [0, 0, 0, 1, 0], [1, 0, 1, 0, 1]] Output: 1 Explanation: There is only one corner rectangle, with corners grid[1][2], grid[1][4], grid[3][2], grid[3][4].
Example 2:
Input: grid = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] Output: 9 Explanation: There are four 2x2 rectangles, four 2x3 and 3x2 rectangles, and one 3x3 rectangle.
Example 3:
Input: grid = [[1, 1, 1, 1]] Output: 0 Explanation: Rectangles must have four distinct corners.
Note:
- The number of rows and columns of
grid
will each be in the range[1, 200]
. - Each
grid[i][j]
will be either0
or1
. - The number of
1
s in the grid will be at most6000
.
解题思路:
一开始想到的是暴力破解法:即对每一个点进行检查以它为左上角的矩形的个数。
先向下走,再向右走,最后再向上走,复杂度我认为是O(n4)
看到了别人提交的较快的方法,实际上是进行了剪枝,因为若能构成矩形,必定有另一个顶点在同一行。
我们记录改顶点往后的为1的 j 值,对后面的每一行检查对应的两个顶点的值是否为1
代码:
class Solution { public: int countCornerRectangles(vector<vector<int>>& grid) { if(grid.size() <= 1 || grid[0].size() <= 1) return 0; int ret = 0; for(int i = 0; i < grid.size() - 1; i++){ for(int j = 0; j < grid[0].size() - 1; j++){ if(grid[i][j] == 1) ret += findRec(grid, i, j); } } return ret; } int findRec(vector<vector<int>> &grid, int i, int j){ int ret = 0; for(int x = i+1; x < grid.size(); x++){ if(grid[x][j] == 1){ for(int y = j+1; y < grid[0].size(); y++){ if(grid[x][y] == 1 && grid[i][y] == 1) ret++; } } } return ret; } };
较快的方法:
classclass SolutionSolution { { publicpublic: : intint countCornerRectanglescountCornerRectangles((vectorvector<<vectorvector<<intint>>& grid)>>& grid) { { ifif(grid.empty() || grid[(grid.empty() || grid[00].empty()){ ].empty()){ return 0; } int res = 0; int row = grid.size(), col = grid[0].size(); for(int i = 0; i < row-1; i++){ vector<int> ones; for(int j = 0; j < col; j++){ if(grid[i][j] == 1){ ones.push_back(j); } } for(int k = i+1; k < row; k++){ int cur = 0; for(auto o:ones){ if(grid[k][o] == 1){ cur++; } } res += cur*(cur-1)/2; } } return res; } };