我发现了无数问题,询问如何在2D数组中找到最大的连续矩形,还有一些询问矩形的数目,但是只有一个涉及查找所有矩形的坐标,宽度和高度的问题。在1s和0s的2D中覆盖1s区域所需的矩形。
问题(Finding rectangles in a 2d block grid)可以解决,但由于引用了外部代码块而难以理解。
我正在处理组成字母像素的2D阵列:
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
此处所需的输出如下:
[[4,0,6,17],[7,0,16,2],[7,7,15,9],[7,15,15,17]]
每个数组都包含左上角坐标和右下角坐标(任何获得左上角,宽度和高度的方法都可以使用)。
有人可以为先前提出的问题或其他可行的算法提供伪代码(或Javascript),还是对所需的步骤提供更深入的说明?
答案 0 :(得分:1)
这是一种使用简单算法的方法。
const mat = [
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//0
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//1
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//2
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//3
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//4
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//5
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//6
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],//7
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],//8
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],//9
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//10
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//11
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//12
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//13
[0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],//14
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//15
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],//16
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0] //17
];
const W = mat[0].length;
const H = mat.length;
// get the area covered by rectangles
let totalRectArea = 0;
for (let i = 0; i < W; ++i) {
for (let j = 0; j < H; ++j) {
totalRectArea += mat[j][i] > 0 ? 1 : 0;
}
}
const rects = [];
let rectArea = 0;
// find all rectangle until their area matches the total
while (rectArea < totalRectArea) {
const rect = findNextRect();
rects.push(rect);
markRect(rect);
rectArea += (rect.x2 - rect.x1 + 1) * (rect.y2 - rect.y1 + 1);
}
console.log(rects);
function findNextRect() {
// find top left corner
let foundCorner = false;
const rect = { x1: 0, x2: W-1, y1: 0, y2: H-1 };
for (let i = 0; i < W; ++i) {
for (let j = 0; j < H; ++j) {
if (mat[j][i] === 1) {
rect.x1 = i;
rect.y1 = j;
foundCorner = true;
break;
}
}
if (foundCorner) break;
}
// find bottom right corner
for (let i = rect.x1; i <= rect.x2; ++i) {
if (mat[rect.y1][i] !== 1) {
rect.x2 = i-1;
return rect;
}
for (let j = rect.y1; j <= rect.y2; ++j) {
if (mat[j][i] !== 1) {
rect.y2 = j-1;
break;
}
}
}
return rect;
}
// mark rectangle so won't be counted again
function markRect({ x1, y1, x2, y2 }) {
for (let i = x1; i <= x2; ++i) {
for (let j = y1; j <= y2; ++j) {
mat[j][i] = 2;
}
}
}