简体   繁体   中英

How to reduce time complexity in this problem

I have been recently asked this question in an interview and I am wondering how to answer this.

You have a 2D matrix of binary digits in any random order
0 0 0 0 0 0 0 0
1 0 0 1 1 1 1 0
1 0 0 0 1 1 1 1
1 0 1 1 0 1 1 0
1 1 0 0 0 0 1 1
1 0 1 0 1 1 0 0

And you need to find the occurance of this pattern
1
11

So, looking at the above matrix it is evident that the answer is 6 . And I solved it like this

unsigned int Findpairs(const std::vector<std::vector<unsigned int>>& A) {
    unsigned int count = 0;

    for (unsigned int i = 0; i < (A.size()-1); i++) {
        for (unsigned int j = 0; j < (A[i].size()-1); j++){
            if(A[i][j]==1 && A[i+1][j]==1 && A[i+1][j+1]==1){
                count++;
            }
        }
    }

    return (count);
}

The next question was to get a better time complexity. I could not answer the exact solution .

Can someone help me with this? I just want to know this for my own curiosity.

Here is a small optimization which is dependent on the input pattern.

unsigned int Findpairs(const std::vector<std::vector<unsigned int>>& A) {
    unsigned int count = 0;

    for (unsigned int i = 0; i < (A.size() - 1); i++) {
        for (unsigned int j = 0; j < (A[i].size() - 1); j++) {
            if (A[i + 1][j + 1] == 1) {
                if (A[i + 1][j] == 1 && A[i][j] == 1) {
                    count++;
                }
            }
            else {
                j++; //skip a column because our bottom right saw 0
            }
        }
    }

    return (count);
}

The time complexity of your operation could be described as O(n) where n is the number of points in your array. Your operation is equivalent to searching for something in an unsorted array. There are ways you may make your algorithm more efficient but you can not perform this type of search in less than linear time, O(n).

For some problems, you can improve the time complexity by first sorting or collecting additional information about the problem. In the case of this problem, you can prove that your solution is linearly related to the size of the array. With a random array, each of the 3 elements has a 50% chance of occurring. For each n, the odds of the pattern occuring is 0.5^3 = 1/8. That means you will count about 1/8*n occurrences of the pattern. Counting the pattern alone takes O(n) time.

If your goal was to Estimate the number of occurrences in a random array, you can give an estimate in O(1) time. This pattern should occur about 1/8*(j-1)*(i-1) times in a random array.

As for the concrete problem, your solution is appropriate.

There are 2 alternative methods that would be beneficial in case of you want to find other patterns in the same matrix or in case of very big matrices and bigger patterns:

https://en.wikipedia.org/wiki/Summed-area_table

https://en.wikipedia.org/wiki/Discrete_Fourier_transform

both require some preprocessing of the original matrix, but will then provide faster checks for pattern templates. Youll find implemetations for both in the OpenCV image processing library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM