764. Largest Plus Sign
问题描述:
In a 2D grid
from (0, 0) to (N-1, N-1), every cell contains a 1
, except those cells in the given list mines
which are 0
. What is the largest axis-aligned plus sign of 1
s contained in the grid? Return the order of the plus sign. If there is none, return 0.
An "axis-aligned plus sign of 1
s of order k" has some center grid[x][y] = 1
along with 4 arms of length k-1
going up, down, left, and right, and made of 1
s. This is demonstrated in the diagrams below. Note that there could be 0
s or 1
s beyond the arms of the plus sign, only the relevant area of the plus sign is checked for 1s.
Examples of Axis-Aligned Plus Signs of Order k:
Order 1: 000 010 000 Order 2: 00000 00100 01110 00100 00000 Order 3: 0000000 0001000 0001000 0111110 0001000 0001000 0000000
Example 1:
Input: N = 5, mines = [[4, 2]] Output: 2 Explanation: 11111 11111 11111 11111 11011 In the above grid, the largest plus sign can only be order 2. One of them is marked in bold.
Example 2:
Input: N = 2, mines = [] Output: 1 Explanation: There is no plus sign of order 2, but there is of order 1.
Example 3:
Input: N = 1, mines = [[0, 0]] Output: 0 Explanation: There is no plus sign, so return 0.
Note:
N
will be an integer in the range[1, 500]
.mines
will have length at most5000
.mines[i]
will be length 2 and consist of integers in the range[0, N-1]
.- (Additionally, programs submitted in C, C++, or C# will be judged with a slightly smaller time limit.)
解题思路:
求当前矩阵中能够构成的最大的加号的大小。
加号的4条边要求等长。
我们可以用两个辅助矩阵:leftUp,rightDown分别记录该点上左,下右最长的连续的边。
然后遍历矩阵。当元素为1的时候,可以作为加号的中心,取上下左右最短的边作为加号的边。
加号的大小为边的长度+1.
代码:
class Solution { public: int orderOfLargestPlusSign(int N, vector<vector<int>>& mines) { vector<vector<int>> mtx(N, vector<int>(N, 1)); for(auto m : mines){ mtx[m[0]][m[1]] = 0; } vector<vector<pair<int,int>>> leftUp(N, vector<pair<int,int>>(N, {0,0})); for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ int l = 0, u = 0; if(i-1 > -1){ if(mtx[i-1][j] == 1) u = leftUp[i-1][j].first+1; } if(j-1 > -1){ if(mtx[i][j-1] == 1) l = leftUp[i][j-1].second+1; } leftUp[i][j] = {u, l}; } } vector<vector<pair<int, int>>> rightDown(N, vector<pair<int, int>>(N)); for(int i = N-1; i > -1; i--){ for(int j = N-1; j > -1; j--){ int r = 0, d = 0; if(i+1 < N){ if(mtx[i+1][j] == 1) d = rightDown[i+1][j].first+1; } if(j+1 < N){ if(mtx[i][j+1] == 1) r = rightDown[i][j+1].second+1; } rightDown[i][j] = {d, r}; } } int ret = 0; for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ if(mtx[i][j] == 1){ int lu = min(leftUp[i][j].first, leftUp[i][j].second); int rd = min(rightDown[i][j].first, rightDown[i][j].second); int len = min(lu , rd); ret = max(len+1, ret); } } } return ret; } };