18. Number of Islands II

Link to the problem

Description

A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand operation which turns the water at position (row, col) into a land. Given a list of positions to operate, count the number of islands after each addLand operation. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Can you do it in time complexity O(k log mn), where k is the length of the positions?

Example

Given m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]].
Initially, the 2d grid grid is filled with water. (Assume 0 represents water and 1 represents land).

0 0 0
0 0 0
0 0 0
Operation #1: addLand(0, 0) turns the water at grid[0][0] into a land.

1 0 0
0 0 0 Number of islands = 1
0 0 0
Operation #2: addLand(0, 1) turns the water at grid[0][1] into a land.

1 1 0
0 0 0 Number of islands = 1
0 0 0
Operation #3: addLand(1, 2) turns the water at grid[1][2] into a land.

1 1 0
0 0 1 Number of islands = 2
0 0 0
Operation #4: addLand(2, 1) turns the water at grid[2][1] into a land.

1 1 0
0 0 1 Number of islands = 3
0 1 0
We return the result as an array: [1, 1, 2, 3]

Idea

Use a union find data structure. Each time a one is inserted, make it its own parent, and add edges to its neighboring ones.

Solution

class UnionFind {
public:
    UnionFind(int m, int n) {
        count = 0, capacity = 0;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                parent.push_back(-1);
                rank.push_back(0);
                capacity++;
            }
        }
    }
    
    int getParent(int node) {
        if (parent[node] != node) {
            parent[node] = getParent(parent[node]);
        }
        return parent[node];
    }
    
    bool contains(int node) {
        return (node >= 0) && (node < capacity) && parent[node] >= 0;
    }
    
    bool setParent(int node) {
        if (parent[node] < 0) {
            parent[node] = node;
            rank[node] = 1;
            count++;
            return true;
        }
        return false;
    }
    
    void join(int node1, int node2) {
        int group1 = getParent(node1);
        int group2 = getParent(node2);
        if (group1 != group2) {
            count--;
            // Join two groups
            int rank1 = rank[group1], rank2 = rank[group2];
            if (rank1 < rank2) {
                parent[group1] = group2;
            } else if (rank1 > rank2) {
                parent[group2] = group1;
            } else {
                parent[group1] = group2;
                rank[group2]++;
            }
        }
    }
    
    int getCount() {
        return count;
    }
    
private:
    int count;
    int capacity;
    vector<int> parent;
    vector<int> rank;
};

class Solution {
public:
    vector<int> numIslands2(int m, int n, vector<pair<int, int>> &positions) {
        UnionFind uf(m, n);
        vector<int> rtn;
        for (auto pos = positions.begin(); pos != positions.end(); ++pos) {
            int node = pos->first * n + pos->second;
            if (uf.setParent(node)) {
                if (node % n && uf.contains(node - 1)) uf.join(node, node - 1);
                if (uf.contains(node - n)) uf.join(node, node - n);
                if ((node + 1) % n && uf.contains(node + 1)) uf.join(node, node + 1);
                if (uf.contains(node + n)) uf.join(node, node + n);                
            }
            rtn.push_back(uf.getCount());
        }
        return rtn;
    }
};

158 / 158 test cases passed.
Runtime: 100 ms

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市酗钞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌执俩,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壹粟,死亡現(xiàn)場離奇詭異缀皱,居然都是意外死亡,警方通過查閱死者的電腦和手機事扭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乐横,“玉大人求橄,你說我怎么就攤上這事∑瞎” “怎么了罐农?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長催什。 經(jīng)常有香客問我涵亏,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任溯乒,我火速辦了婚禮,結(jié)果婚禮上豹爹,老公的妹妹穿的比我還像新娘裆悄。我一直安慰自己,他們只是感情好臂聋,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布光稼。 她就那樣靜靜地躺著,像睡著了一般孩等。 火紅的嫁衣襯著肌膚如雪艾君。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天肄方,我揣著相機與錄音冰垄,去河邊找鬼。 笑死权她,一個胖子當(dāng)著我的面吹牛虹茶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播隅要,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蝴罪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了步清?” 一聲冷哼從身側(cè)響起要门,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎廓啊,沒想到半個月后欢搜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡谴轮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年狂巢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片书聚。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡唧领,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雌续,到底是詐尸還是另有隱情斩个,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布驯杜,位于F島的核電站受啥,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜滚局,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一居暖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧藤肢,春花似錦太闺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至最住,卻和暖如春钞澳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涨缚。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工轧粟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脓魏。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓逃延,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轧拄。 傳聞我的和親對象是個殘疾皇子揽祥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容

  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,476評論 0 23
  • 很多人都知道,我喜歡冬天檩电。不是我抗凍拄丰,也不是我喜歡寒冷的天氣,更不是因為我懶俐末。 不知道你們有沒有感...
    行走的大白鯊閱讀 263評論 0 0
  • 無意看到這條微博料按。 真的沒看出來王柏川對樊勝美哪里是真愛。 首先就是追學(xué)生時代喜歡的女神卓箫,追到最后也不知道是還喜歡...
    小嫽閱讀 523評論 0 0
  • 漁人碼頭(Fisherman's Wharf)载矿,地處舊金山的太平洋海岸,是舊金山的象征之一烹卒。一個個依水而建的碼頭闷盔,...
    田園牧歌123閱讀 989評論 0 0