线性时间数计算为1

时间:2018-02-15 03:36:47

标签: algorithm

  

n x n数组A的每一行由1和0组成,因此,在A的任何行i中,所有1都在该行中的任何0之前。对于i = 0,1,...,n-2,行i中的1的数量> =行i + 1中的1的数量。 A已经在内存中,描述了在O(n)时间运行的方法,用于计算数组A中1的数量。

我因为时间复杂而陷入困境。知道怎么办吗?

2 个答案:

答案 0 :(得分:0)

我们所知道的:(1)1的数量在行与行之间没有增加,(2)每行中的所有1来自"在&#之前34; (让我们左边说)零。

现在假设你从第一行开始并一直计算1直到达到第一个零(在第一行)。调用该1符合零的索引i

当你向下移动到每一行时,你会以哪种方式找到该行的i? (提示:你永远不会向右走。)

现在想一想,如果从同一个索引开始的每一行中,最多可以i移动多少个单元格,然后向左移动以找到i(其中零和{{1} 那个行。你总共访问了多少行?加上这两个,你就会有复杂性。

答案 1 :(得分:0)

问题可以在 O(R+C) 中解决,其中 R 表示行数, C 表示列数。

这个想法很简单

  

i 中的1的数量是> =行中的1的数量 i+1

这也意味着,

  

i 中的0的数量是< = i+1 行中的0的数量

计算 1 st 行中 0 的数量,这可以在 O(R)中完成时间。要计算 2 nd 行中 0 的数量,您不需要从头开始计数,因为此行有更多(或等于 0 比上一行。

参考示例以获得更好的解释。

Example:

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

First Row:  // Count number of 0's from backwards, only 1 zero in this case, so number of 1's = Column count(C) - number of 0's i.e. 3
 1  1  1  0

Second Row: // Iterate from current index towards left until 1st 1, so now no. of 0's is 3 so no. if 1's = C - no. of 0's = 1
 1  1  1  0
          |
 1  0  0  0
   <- <- <-

Third Row:
 1  1  1  0
          |
 1  0  0  0
   <- <- <-
    |
 0  0  0  0
<- <-
no. of 1's = C - no. of 0's = 0

只需添加全部否。 1的。答案是3 + 1 + 0 = 4

Live Code

#include <iostream>
using namespace std;

int arr[6][4] = {
    1,1,1,1,1,0,
    1,1,1,1,0,0,
    1,1,0,0,0,0,
    1,0,0,0,0,0
};

int countOnes(){
    int ans = 0, r = 6, c = 4, i = 0, j = c - 1;
    for(i = 0; i < r; i++){
        while(j>=0 && arr[i][j]==0)
            j--;
        ans+=(j+1);
    }
    return ans;
}

int main() {
    int onesCount = countOnes();
    cout<<onesCount;
    return 0;
}