LintCode-岛屿的个数II

434. 岛屿的个数II

给定 n,m,分别代表一个2D矩阵的行数和列数,同时,给定一个大小为 k 的二元数组A。起初,2D矩阵的行数和列数均为 0,即该矩阵中只有海洋。二元数组有 k 个运算符,每个运算符有 2 个整数 A[i].x, A[i].y,你可通过改变矩阵网格中的A[i].x],[A[i].y] 来将其由海洋改为岛屿。请在每次运算后,返回矩阵中岛屿的数量。

注意事项

0 代表海,1 代表岛。如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。

样例

给定 n = 3, m = 3, 二元数组 A = [(0,0),(0,1),(2,2),(2,1)].

返回 [1,1,2,2].


这题用到了类似并查集的思路,题目不算难,但自己给自己挖了个大坑:
x = parent[x][y].x;
y = parent[x][y].y;
还有set并不是很方便,改一改是可以不用的。
在查找root的过程中可以进行压缩路径,将父节点指向上一级的指针设置为祖父节点指向的上一级指针,可以大幅减少查找时的时间开销。

主要思路是将新增岛屿的root设为自己,将上下左右四个方向连接的岛屿(如果有)的root->root指向自己,每次操作必定使(最多)五块岛屿合为一个,用1减去操作之前四周岛屿的不同root数量即为岛屿数变化量。也可在在周围四块岛屿查找root结束时判断root是否指向新增岛屿,若不是则岛屿数量-1。参考https://www.cnblogs.com/grandyang/p/5190419.html,这种方法不用进行岛屿查重,会方便很多。

struct NPoint {
    int x;
    int y;
    NPoint() : x(-1), y(-1) {}
    NPoint(int a, int b) : x(a), y(b) {}
    NPoint(Point& a) : x(a.x), y(a.y) {}
    bool operator < (const NPoint &a) const 
    { 
        if (this->x == a.x && this->y == a.y)
            return false;
        else {
            if (this->y != a.y)
                return this->y > a.y;
            else
                return this->x > a.x;
        }
    }
};
class Solution {
public:
    /*
    * @param n: An integer
    * @param m: An integer
    * @param operators: an array of point
    * @return: an integer array
    */
    vector<int> numIslands2(int n, int m, vector<Point> &operators) {
        // write your code here
        int count = 0;
        vector<int> result;
        vector<vector<int>> map(n, vector<int>(m));
        vector<vector<NPoint>> parent(n, vector<NPoint>(m));

        auto getroot = [&](int x, int y) {
            while (parent[x][y].x != x || parent[x][y].y != y) {
                //x = parent[x][y].x;//注意
                //y = parent[x][y].y;
                int xtmp = parent[x][y].x;
                int ytmp = parent[x][y].y;
                parent[x][y].x=parent[xtmp][ytmp].x;
                parent[x][y].y=parent[xtmp][ytmp].y;
                y = ytmp;
                x = xtmp;
            }
            return NPoint(x, y);
        };
        for (Point& p : operators) {
            if (map[p.x][p.y] == 1) {
                result.push_back(count); 
                continue;
            }
            if (map[p.x][p.y] == 0) {
                vector<NPoint> ps;
                if (p.x>0)
                    if (map[p.x - 1][p.y] == 1) ps.push_back(NPoint(p.x - 1, p.y));
                if (p.y>0)
                    if (map[p.x][p.y - 1] == 1) ps.push_back(NPoint(p.x, p.y - 1));
                if (p.x<n - 1)
                    if (map[p.x + 1][p.y] == 1) ps.push_back(NPoint(p.x + 1, p.y));
                if (p.y<m - 1)
                    if (map[p.x][p.y + 1] == 1) ps.push_back(NPoint(p.x, p.y + 1));
                set<NPoint> num;
                for (NPoint point : ps) {
                    num.insert(getroot(point.x, point.y));
                }
                int n1 = num.size();
                for (NPoint point : num) {
                    parent[point.x][point.y] = NPoint(p.x, p.y);
                }
                ps.push_back(p);
                map[p.x][p.y] = 1;
                parent[p.x][p.y]=NPoint(p.x,p.y);
                count += 1 - n1;
                result.push_back(count);
            }
        }
        return result;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章