|
| 1 | +/** |
| 2 | + * @param {number[][]} matrix |
| 3 | + * @return {number[]} |
| 4 | + * |
| 5 | + * dp[i][j].h: 以 i,j 点为最右边端点的横线长度 |
| 6 | + * dp[i][j].v: 以 i,j 点为最下边端点的竖线长度 |
| 7 | + * 如果 i,j 位置是黑色像素(0), 则必然存在 [i, j, 1] 的方阵, 然后取横线和竖线的最短长度 k |
| 8 | + * result[2] 是当前方阵最大长度, 我们需要遍历 [k, result[2]) 左闭右开, 来寻找更长的方阵 |
| 9 | + * 对于任意 k, 需要满足 3 个条件, 则方阵成立 |
| 10 | + * 1. 如果 matrix[i - k + 1][j - k + 1] 是黑色像素, 则方阵左上角成立 |
| 11 | + * 2. 如果 dp[i - k + 1][j].h >= k, 即以方阵右上角点为端点的横线长度大于等于 k, 则方阵右上角成立 |
| 12 | + * 3. 如果 dp[i][j - k + 1].v >= k, 即以方阵坐下角点为端点的竖线长度大于等于 k, 则方阵左下角角成立 |
| 13 | + */ |
| 14 | +var findSquare = function (matrix) { |
| 15 | + const dp = []; |
| 16 | + for (let i = 0; i < matrix.length; i++) { |
| 17 | + dp[i] = []; |
| 18 | + for (let j = 0; j < matrix[i].length; j++) { |
| 19 | + dp[i][j] = {}; |
| 20 | + dp[i][j].h = matrix[i][j] === 0 ? ((dp[i] && dp[i][j - 1] && dp[i][j - 1].h) || 0) + 1 : 0; |
| 21 | + dp[i][j].v = |
| 22 | + matrix[i][j] === 0 ? ((dp[i - 1] && dp[i - 1][j] && dp[i - 1][j].v) || 0) + 1 : 0; |
| 23 | + } |
| 24 | + } |
| 25 | + |
| 26 | + let result = []; |
| 27 | + for (let i = 0; i < dp.length; i++) { |
| 28 | + for (let j = 0; j < dp[i].length; j++) { |
| 29 | + if (matrix[i][j] === 0) { |
| 30 | + if (result.length === 0) { |
| 31 | + result = [i, j, 1]; |
| 32 | + } |
| 33 | + const { h, v } = dp[i][j]; |
| 34 | + for (let k = Math.min(h, v); k > result[2]; k--) { |
| 35 | + if ( |
| 36 | + matrix[i - k + 1] && |
| 37 | + matrix[i - k + 1][j - k + 1] === 0 && |
| 38 | + (dp[i - k + 1] && dp[i - k + 1][j] ? dp[i - k + 1][j].h : 0) >= k && |
| 39 | + (dp[i] && dp[i][j - k + 1] ? dp[i][j - k + 1].v : 0) >= k |
| 40 | + ) { |
| 41 | + result = [i - k + 1, j - k + 1, k]; |
| 42 | + break; |
| 43 | + } |
| 44 | + } |
| 45 | + } |
| 46 | + } |
| 47 | + } |
| 48 | + return result; |
| 49 | +}; |
0 commit comments