英文:
Count the number of positions in a matrix which form a rectangle
问题
我有一个只包含0和1的方阵。例如,
1 0 1 1 1
1 1 0 0 1
1 0 1 1 0
0 1 1 1 1
1 0 1 1 1
我想要统计拥有1作为顶点、其边平行于矩阵的行和列的矩形的数量。矩形的边上可以有0。以下是这样一个矩形的示例(其顶点用方括号表示)
[1] 0 1 1 [1]
1 1 0 0 1
1 0 1 1 0
0 1 1 1 1
[1] 0 1 1 [1]
英文:
I have a square matrix which contains only 0's and 1's. For example,
1 0 1 1 1
1 1 0 0 1
1 0 1 1 0
0 1 1 1 1
1 0 1 1 1
I would like to count the number of rectangles which have 1's as their vertices and which edges are parallel to rows and columns of the matrix. It is allowed to have 0's on the rectangle's edge. Here is an example of such a rectangle (its vertices are in square brackets)
[1] 0 1 1 [1]
1 1 0 0 1
1 0 1 1 0
0 1 1 1 1
[1] 0 1 1 [1]
答案1
得分: 2
在最坏的情况下,矩阵中没有零,因此它可以有O(𝑛^2)个左上角和与同样多的右下角组合在一起,形成O(𝑛^4)个矩形。
所以如果你必须输出每个矩形,时间复杂度将是O(𝑛^4)。但是由于你只需要计算矩形的数量而不是生成矩形本身,你可以节省一些时间,使用时间复杂度为O(𝑛^3)的方法来完成。
思路是选择每一对可能的行,然后计算有多少列在这两行中都有1。每一对2x2的组合都应该被计算。这是一个三角数:如果1-1对的数量为𝑛,那么可以用这些对创建的矩形数量为𝑛(𝑛-1)/2。
JavaScript中的实现:
function countRectangles(rect) {
let count = 0;
for (let y2 = 1; y2 < rect.length; y2++) {
for (let y1 = 0; y1 < y2; y1++) {
let pairs = 0;
for (let x = 0; x < rect[0].length; x++) {
if (rect[y1][x] + rect[y2][x] == 2) {
pairs++;
}
}
// 计算两对角可以组合的方式
count += pairs * (pairs - 1) / 2;
}
}
return count;
}
const rect = [
[1, 0, 1, 1, 1],
[1, 1, 0, 0, 1],
[1, 0, 1, 1, 0],
[0, 1, 1, 1, 1],
[1, 0, 1, 1, 1],
]
console.log(countRectangles(rect)); // 22
希望这有所帮助。
英文:
In the worst case the matrix has no zeroes and thus it can have O(𝑛<sup>2</sup>) top-left corners combined with as many bottom-right corners, making for O(𝑛<sup>4</sup>) rectangles.
So if you would have to output each rectangle, the time complexity would be O(𝑛<sup>4</sup>). But as you only need to count the rectangles and not produce the rectangles themselves, you can save some time and do it with a time complexity of O(𝑛<sup>3</sup>).
The idea is to select every possible pair of rows, and then count how many columns have a 1 in both selected rows. Each combination of 2x2 should be accounted for. This is a triangular number: if the count of 1-1 pairs is 𝑘, then the number of rectangles that can be made with those is 𝑘(𝑘-1)/2.
Implementation in JavaScript:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function countRectangles(rect) {
let count = 0;
for (let y2 = 1; y2 < rect.length; y2++) {
for (let y1 = 0; y1 < y2; y1++) {
let pairs = 0;
for (let x = 0; x < rect[0].length; x++) {
if (rect[y1][x] + rect[y2][x] == 2) {
pairs++;
}
}
// Count in how many ways 2 pairs of corners can be combined
count += pairs * (pairs - 1) / 2;
}
}
return count;
}
const rect = [
[1, 0, 1, 1, 1],
[1, 1, 0, 0, 1],
[1, 0, 1, 1, 0],
[0, 1, 1, 1, 1],
[1, 0, 1, 1, 1],
]
console.log(countRectangles(rect)); // 22
<!-- end snippet -->
答案2
得分: 1
- 针对矩阵中的单元格C执行循环
- 针对可能的矩形尺寸S执行循环,从此单元格开始
- 将found设置为TRUE
- 针对以C为左上角、大小为S的矩形中的单元格R执行循环
- 如果R包含0
- 将found设置为false
- 从R循环中BREAK出来
- 如果R包含0
- 如果found
添加到计数中
- 针对可能的矩形尺寸S执行循环,从此单元格开始
示例:
5x5矩阵
起始单元格1,1(从零开始)
最大矩形为4x4
检查单元格1,4 4,1 和4,4
如果它们都包含1,则找到了一个4x4的矩形
英文:
- LOOP C over cells in the matrix
- LOOP S over possible rectangle sizes, starting from this cell
- Set found TRUE
- LOOP R over cells forming rectangle of size S with top left at C
- IF R contain 0
- SET found false
- BREAK from LOOP R
- IF found
Add to count
Example:
matrix 5 by 5
start cell 1,1 ( zero-based )
maximum rectangle is 4 by 4
check cells at 1,4 4,1 and 4,4
if all contain 1s you have found a 4 by 4 rectangle
答案3
得分: 1
代码部分不需要翻译,以下是翻译好的部分:
"Since the complexity will be at least as high as the length of the output anyway, you might as well bruteforce this."
"生成矩形函数"
"matrix = np.array([[int(x) for x in row.split()] for row in"
"1 0 1 1 1"
"1 1 0 0 1"
"1 0 1 1 0"
"0 1 1 1 1"
"1 0 1 1 1'.split('\n')])"
"print(list(gen_rectangles(matrix)))"
"[(0, 0, 2, 2), (0, 0, 4, 2), (0, 0, 2, 3), (0, 0, 4, 3), (0, 0, 1, 4), (0, 0, 4, 4), (1, 0, 4, 4), (2, 0, 4, 2), (2, 0, 4, 3), (1, 1, 3, 4), (0, 2, 2, 3), (0, 2, 3, 3), (0, 2, 4, 3), (0, 2, 3, 4), (0, 2, 4, 4), (2, 2, 3, 3), (2, 2, 4, 3), (3, 2, 4, 3), (3, 2, 4, 4), (0, 3, 3, 4), (0, 3, 4, 4), (3, 3, 4, 4)]"
英文:
Since the complexity will be at least as high as the length of the output anyway, you might as well bruteforce this.
def gen_rectangles(matrix):
height, width = matrix.shape
for left in range(width):
for top in range(height):
if matrix[top, left] == 1:
for right in range(left+1, width):
if matrix[top, right] == 1:
for bottom in range(top+1, height):
if matrix[bottom, left] == matrix[bottom, right] == 1:
yield (top, left, bottom, right)
import numpy as np
matrix = np.array([[int(x) for x in row.split()] for row in
'''1 0 1 1 1
1 1 0 0 1
1 0 1 1 0
0 1 1 1 1
1 0 1 1 1'''.split('\n')])
print(list(gen_rectangles(matrix)))
# [(0, 0, 2, 2), (0, 0, 4, 2), (0, 0, 2, 3), (0, 0, 4, 3), (0, 0, 1, 4), (0, 0, 4, 4), (1, 0, 4, 4), (2, 0, 4, 2), (2, 0, 4, 3), (1, 1, 3, 4), (0, 2, 2, 3), (0, 2, 3, 3), (0, 2, 4, 3), (0, 2, 3, 4), (0, 2, 4, 4), (2, 2, 3, 3), (2, 2, 4, 3), (3, 2, 4, 3), (3, 2, 4, 4), (0, 3, 3, 4), (0, 3, 4, 4), (3, 3, 4, 4)]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论