统计矩阵中形成矩形的位置数。

huangapple go评论60阅读模式
英文:

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]

我查看了链接1链接2,但仍然不清楚。

英文:

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]

I have looked into link1 and link2 but still have no clue..

答案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 &lt; rect.length; y2++) {
        for (let y1 = 0; y1 &lt; y2; y1++) {
            let pairs = 0;
            for (let x = 0; x &lt; 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出来
      • 如果found
        添加到计数中

示例:

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
&#39;&#39;&#39;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&#39;&#39;&#39;.split(&#39;\n&#39;)])

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)]

huangapple
  • 本文由 发表于 2023年2月24日 00:16:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75547465.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定