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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章