给定一个2D矩阵,每列占用一系列块,找到每行占用的块数

时间:2015-08-11 06:35:32

标签: arrays algorithm

我们有一个nXn矩阵。 我们给出了n行输入。 每行i(从0开始)有两个整数l& r对应于列i,并指定该列中的块占用的范围为l到r(0索引)。

我们必须使用另一个数组来查找每行中该2d矩阵中的块数,以存储每个行号的值。 例如, 我们给出n = 5。 和输入,

1 3
2 3
1 3
2 3
1 2

我们必须给出一个大小为n的数组,每个索引给出2 d矩阵中相应行占用的块数。 例如,在上述情况下, 2 D矩阵看起来像

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

(0代表空置,1代表占用) ans将是 0 3 5 4 0

我可以在o(n ^ 2)中执行此操作。

我们有什么办法可以在O(n)???

中完成

2 个答案:

答案 0 :(得分:2)

是的,你可以。

这个想法是知道当前行占用了多少个单元格并知道间隔在下一行开始和结束的方式,您可以轻松计算下一行的占用率:占用 next =占用 prev + starts - ends。

已更新:我提出了更简单的解决方案。

创建两个大小为N的int数组,将它们命名为beginsends。用零初始化所有这些。对于每个间隔,在索引处增加begins数组,该索引对应于起始索引的间隔,并在间隔结束索引处递减endsbegins[intervalStart]++ ends[intervalEnd]--

创建计数器occupied=0。现在循环rowIndex从0到N-1。对于每次迭代occupied = occupied + begins[rowIndex] + ends[rowIndex-1](仔细检查数组边界)。之后occupied将保留当前行(rowIndex)的确切已占用单元格数。

答案 1 :(得分:0)

@Aivean拥有正确的算法。如果进行以下观察,可以进一步简化它。

每个块对,比如[p q],引入从索引p(包括)开始到索引q + 1结束的间隔的增量(不包括)。这意味着可以维护单个数组,例如deltas,并且对于每个块对,递增deltas[p]并递减deltas[q + 1](如果存在)。

要获得每行占用块数的预期结果,可以生成一个累加和的数组。

以下是Javascript中的算法实现:

var m = [[1, 3],
         [2, 3],
         [1, 3],
         [2, 3],
         [1, 2]];

m.reduce(
    function (deltas, pair) {
        /* For each block (pair) in the matrix,
           increment the delta for the beginning row (inclusive). */
        ++deltas[pair[0]];
        /* Decrement the delta for the row after the ending row (exclusive),
           if it exists. */
        pair[1] + 1 < m.length && --deltas[pair[1] + 1];
        return deltas;
    },
    /* Generate an array of zeroes as the initial value of deltas. */
    m.map(Number.prototype.valueOf, 0))
.reduce(
    function (acc, delta) {
        /* Find the cumulative sum from each delta, starting with zero. */
        delta += acc[acc.length - 1] || 0;
        /* Build up an array of cumulative sums. */
        acc.push(delta);
        return acc;
    }, []);

以下是此计算的结果值:

[0, 3, 5, 4, 0]

上面的代码调用map一次,reduce两次,每次都是O(N)操作。

相关问题