可以在一个位图计数连续的区域在O(R * C)来改善?位图、在一、区域

由网友(击中你的心)分享简介:正在给出一个satellite.The图像拍摄的表面的图像时,其中的水带标记的位图。土地的特点是' * 。相邻组 * 的形成一个小岛。 (二' * '是如果他们是水平,垂直或对角线邻域相邻)。你的任务是打印岛屿位图的数量。You are given an image of a surface photographed...

正在给出一个satellite.The图像拍摄的表面的图像时,其中的水带标记的位图。土地的特点是' * 。相邻组 * 的形成一个小岛。 (二' * '是如果他们是水平,垂直或对角线邻域相邻)。你的任务是打印岛屿位图的数量。

You are given an image of a surface photographed by a satellite.The image is a bitmap where water is marked by '.' and land is marked by '*'. Adjacent group of '*'s form an island. (Two '*' are adjacent if they are horizontal, vertical or diagonal neighbours). Your task is to print the number of islands in the bitmap.

例输入: -

.........**
**......***
...........
...*.......
*........*.
*.........*

输出: - 5

Output:- 5

下面,是我实现它接受 O(R * C)的空间和 O(R * C)空间,其中r是总无。行和c是COLS的总无

Here, is my implementation which takes O(r * c) space and O(r * c) space where r is total no. of rows and c is total no of cols.

#include <stdio.h>
#define COLS 12

void markVisted(char map[][COLS], int visited[][COLS], int row, int col, int rowCount)
{
    if((row < 0) || (row >= rowCount) || (col < 0) || (col >= COLS) || (map[row][col] != '*') || (visited[row][col] == 1)) return;

    visited[row][col] = 1;

    //calling neighbours
    markVisted(map, visited, row+1, col, rowCount);
    markVisted(map, visited, row, col+1, rowCount);
    markVisted(map, visited, row-1, col, rowCount);
    markVisted(map, visited, row, col-1, rowCount);
    markVisted(map, visited, row+1, col+1, rowCount);
    markVisted(map, visited, row-1, col-1, rowCount);
    markVisted(map, visited, row-1, col+1, rowCount);
    markVisted(map, visited, row+1, col-1, rowCount);
}
int countIslands(char map[][COLS], int visited[][COLS], int rowCount)
{
    int i, j, count = 0;
    for(i=0; i<rowCount; ++i){
        for(j=0; j<COLS; ++j){

            if((map[i][j] == '*') && (visited[i][j] == 0)){
                ++count;
                markVisted(map, visited, i, j, rowCount);
            }
        }
    }
    return count;
}

int main()
{
    char map[][COLS] = {
                    "*..........",
                    "**........*",
                    "...........",
                    "...*.......",
                    "*........*.",
                    "..........*"               
                    };
    int rows = sizeof(map)/sizeof(map[0]);
    int visited[rows][COLS], i, j;  

    for(i=0; i<rows; ++i){
        for(j=0; j<COLS; ++j) visited[i][j] = 0;
    }

    printf("No. of islands = %dn", countIslands(map, visited, rows));


    return 0;
}

请提出一些更好的逻辑,对于这个问题 同时,建议,以改善我的解决方案是值得欢迎的。

please suggest some better logic for this problem also, suggestions to improve my solution is welcomed.

推荐答案

我觉得这里的混乱是你的算法并真正以线性时间运行,而不是二次的时间。

I think the confusion here is that your algorithm does actually run in linear time, not quadratic time.

在使用大O表示法, N 为输入的内容。在这里你输入的没有的只是研究或只是 C ,而是研究 * C ,因为它是节点的网格。你的算法 O(R * C),你在你的问题说......因此你的算法运行为O(n)这是线性时间。

When using big-O notation, n stands for the input size. Your input here is not just r or just c, but rather, r * c, as it is a grid of nodes. Your algorithm runs in O(r * c), as you said in your question... thus your algorithm runs in O(n) which is linear time.

有我认为,解决这个问题的任何算法将必须在最坏的情况下读取每个输入细胞一次。因此,最好的运行时间,你可以希望的是 O(N)。当你的算法 O(n)的运行你不能有运行的更快的订单,在最坏的情况下,比你提出的算法的任何算法。

It seems to me that any algorithm that solves this problem will have to read each input cell once in the worst case. Thus the best running time you can hope for is O(n). As your algorithm runs in O(n) you can't have any algorithm that runs of a faster order, in the worst case, than the algorithm you proposed.

我能想到的一些聪明的办法。例如,如果你有 * 个块,你只能检查对角线,在某些情况下。也就是说,如果你有

I can think of some clever tricks. For example, if you have a block of *s, you could only check the diagonals, in certain cases. That is, if you have

......
.****.
.****.
.****.
.****.
......

都不会有问题,如果你只阅读这些细胞:

it won't matter if you only read these cells:

......
.*.*..
..*.*.
.*.*..
..*.*.
......

除非例如你有一些在底部,最左边的角落,你会在这种情况下,需要读的底部,最左边的 * 。因此,也许在某些情况下,你的算法可以运行得更快,但最坏的情况下(这是什么 0 的措施),它必须是 0 (N)

unless for example you have something in the bottom-left-most corner, in which case you would need to read that bottom-left-most *. So maybe in certain cases your algorithm can run more quickly, but for the worst case (which is what O measures), it will have to be O(n).

编辑:另外,即使在这种情况下,你只能读一半节点,运行时会为O(n / 2)这仍然是同阶( O(N))。

Also even in that case where you only read half the nodes, the run-time would be O(n/2) which is still of the same order (O(n)).