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.)
思路:因为对时间有要求,所以不能穷举。使用动态规划。这里的DP比较巧妙。
比如011011111,向右扫描,遇1累加,遇0置0,初值为0。得到012012345。(向右可扩展最大值)
再向左扫描,得到123450120。再对每个位置取最小值。得到每个位置在该行可扩展的最大长度:011012321。(向左可扩展最大值)
同理,垂直方向再进行一次,得到垂直方向上的可扩展最大长度。
最后,综合水平和垂直两个方向。
class Solution {
public int orderOfLargestPlusSign(int N, int[][] mines) {
int[][] dp = new int[N][N];
Set<Integer> mineset = new HashSet<Integer>();
for(int[] mine:mines){
mineset.add(mine[0]*N + mine[1]);//相当于对每一个mine进行编号。
}
int ans = 0;
for(int i = 0;i < N ;i++){
int count = 0;
for(int j = 0;j <N ;j++){
count = mineset.contains(i * N + j)?0:count+1;
dp[i][j] = count;
}
count = 0;
for(int j = N-1;j>=0;j--){
count = mineset.contains(i * N + j)?0:count+1;
dp[i][j] = Math.min(dp[i][j],count);
}
}
for(int j = 0;j < N ;j++){
int count = 0;
for(int i = 0;i <N ;i++){
count = mineset.contains(i * N + j)?0:count+1;
dp[i][j] = Math.min(dp[i][j],count);
}
count = 0;
for(int i = N-1;i>=0;i--){
count = mineset.contains(i * N + j)?0:count+1;
dp[i][j] = Math.min(dp[i][j],count);
ans = Math.max(ans,dp[i][j]);
}
}
return ans;
}
}