数组中的矩形区域

发布于 2024-09-19 13:12:38 字数 70 浏览 5 评论 0原文

给定一个 N*N 矩阵,其中包含 1 和 0,并且给定一个整数 k,找到其中包含 k 个 1 的矩形区域的最佳方法是什么???

Given an N*N matrix having 1's an 0's in them and given an integer k,what is the best method to find a rectangular region such that it has k 1's in it ???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九歌凝 2024-09-26 13:12:38

我可以用 O(N^3*log(N)) 来完成,但肯定最好的解决方案更快。首先创建另一个 N*N 矩阵 B(初始矩阵是 A)。 B 的逻辑如下:

B[i][j] - is the number of ones on rectangle in A with corners (0,0) and (i,j).

您可以通过动态规划以 O(N^2) 计算 B: B[i][j] = B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j]。

现在,通过迭代所有右下 (i=1..N, j=1..N, O(N^2))、左下 ( z=1..j, O(N)) 和右上 (t=1..i, O(N)) 并在 B 的帮助下得到这个矩形中 1 的数量:

sum_of_ones = B[i][j] - B[i][z-1] - B[t-1][j] + B[t-1][z-1].

如果你正好得到k: k==sum_of_ones,然后输出结果。

为了使其成为 N^3*log(N),您应该通过二分搜索找到右上(所以不仅仅是迭代所有可能的单元格)。

I can do it with O(N^3*log(N)), but sure the best solution is faster. First you create another N*N matrix B (the initial matrix is A). The logic of B is the following:

B[i][j] - is the number of ones on rectangle in A with corners (0,0) and (i,j).

You can evaluate B for O(N^2) by dynamic programming: B[i][j] = B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j].

Now it is very easy to solve this problem with O(N^4) by iterating over all right-bottom (i=1..N, j=1..N, O(N^2)), left-bottom (z=1..j, O(N)), and right-upper (t=1..i, O(N)) and you get the number of ones in this rectangular with the help of B:

sum_of_ones = B[i][j] - B[i][z-1] - B[t-1][j] + B[t-1][z-1].

If you got exactly k: k==sum_of_ones, then out the result.

To make it N^3*log(N), you should find right-upper by binary search (so not just iterate all possible cells).

各自安好 2024-09-26 13:12:38

考虑这个更简单的问题:

给定一个大小为 N 且仅包含值 1 和 0 的向量,找到一个恰好包含 k 个值 1 的子序列。

A 为给定向量,并且 S[i] = A[1] + A[2] + A[3] + ... + A[i],表示子序列A[1..i]中有多少个1。

对于每个 i,我们感兴趣的是 j <= i 是否存在,使得 S[i] - S[j-1] == k

我们可以使用以下关系在 O(n) 中通过哈希表找到它:

S[i] - S[j-1] == k => S[j-1] = S[i] - k

let H = an empty hash table
for i = 1 to N do
  if H.Contains (S[i] - k) then your sequence ends at i
  else
    H.Add(S[i])

现在我们可以用它来解决 O(N^3) 中给定的问题:对于给定的每个行序列矩阵(有 O(N^2) 行序列),考虑该序列来表示向量并对其应用之前的算法。在矩阵情况下,S 的计算有点困难,但并不难算出来。如果您需要更多详细信息,请告诉我。

更新:
以下是该算法如何处理以下矩阵,假设 k = 12

0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0

单独考虑第一行:

0 1 1 1 1 0

将其视为向量 0 1 1 1 1 0 并应用更简单问题的算法:我们发现没有子序列加起来等于 12,所以我们继续。

考虑前两行:

0 1 1 1 1 0
0 1 1 1 1 0

将它们视为向量 0+0 1+1 1+1 1+1 1+1 0+0 = 0 2 2 2 2 0 并应用算法更简单的问题:同样,没有子序列加起来等于 12,所以继续。

考虑前三行:

0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0

将它们视为向量 0 3 3 3 3 0 并对其应用更简单问题的算法:我们找到从位置 2 开始并在位置 5 结束的序列成为解决方案。由此我们可以通过简单的记账得到整个矩形。

Consider this simpler problem:

Given a vector of size N containing only the values 1 and 0, find a subsequence that contains exactly k values of 1 in it.

Let A be the given vector and S[i] = A[1] + A[2] + A[3] + ... + A[i], meaning how many 1s there are in the subsequence A[1..i].

For each i, we are interested in the existence of a j <= i such that S[i] - S[j-1] == k.

We can find this in O(n) with a hash table by using the following relation:

S[i] - S[j-1] == k => S[j-1] = S[i] - k

let H = an empty hash table
for i = 1 to N do
  if H.Contains (S[i] - k) then your sequence ends at i
  else
    H.Add(S[i])

Now we can use this to solve your given problem in O(N^3): for each sequence of rows in your given matrix (there are O(N^2) sequences of rows), consider that sequence to represent a vector and apply the previous algorithm on it. The computation of S is a bit more difficult in the matrix case, but it's not that hard to figure out. Let me know if you need more details.

Update:
Here's how the algorithm would work on the following matrix, assuming k = 12:

0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0

Consider the first row alone:

0 1 1 1 1 0

Consider it to be the vector 0 1 1 1 1 0 and apply the algorithm for the simpler problem on it: we find that there's no subsequence adding up to 12, so we move on.

Consider the first two rows:

0 1 1 1 1 0
0 1 1 1 1 0

Consider them to be the vector 0+0 1+1 1+1 1+1 1+1 0+0 = 0 2 2 2 2 0 and apply the algorithm for the simpler problem on it: again, no subsequence that adds up to 12, so move on.

Consider the first three rows:

0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0

Consider them to be the vector 0 3 3 3 3 0 and apply the algorithm for the simpler problem on it: we find the sequence starting at position 2 and ending at position 5 to be the solution. From this we can get the entire rectangle with simple bookkeeping.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文