【Lintcode】434. Number of Islands II

題目地址:

https://www.lintcode.com/problem/number-of-islands-ii/description

給定一個二維00矩陣,再給定一系列座標,每次操作都將某個座標位置的00改爲11,要求動態返回11連通塊的數量。

思路是並查集。一開始先記連通塊數量爲00,同時開一個數組記錄某個位置是否已經是11,接着每遍歷一個座標。如果該座標位置已經是11則略過,否則將這個位置標記爲是11,將連通塊數目加11,接着和其四個鄰居上的11做union操作,每union一次就將連通塊數目減少11,並及時返回連通塊數目。代碼如下:

import java.util.ArrayList;
import java.util.List;

public class Solution {
    
    class UnionFind {
        private int[] parent, rank;
        private boolean[] visited;
        private int group;
        private int cols, rows;
        
        public UnionFind(int n, int rows, int cols) {
            parent = new int[n];
            rank = new int[n];
            // 記錄某個位置是否已經是1
            visited = new boolean[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
                rank[i] = 1;
            }
            
            this.rows = rows;
            this.cols = cols;
        }
        
        public int find(int p) {
            if (p != parent[p]) {
                parent[p] = find(parent[p]);
            }
            
            return parent[p];
        }
        
        public void union(int p, int q) {
            int pRoot = find(p), qRoot = find(q);
            if (pRoot == qRoot) {
                return;
            }
            
            if (rank[pRoot] < rank[qRoot]) {
                parent[pRoot] = qRoot;
            } else if (rank[pRoot] > rank[qRoot]) {
                parent[qRoot] = pRoot;
            } else {
                parent[pRoot] = qRoot;
                rank[qRoot]++;
            }
            
         	// union一次連通塊數目就減少1
            group--;
        }
        
        public void add(Point p) {
            int x = p.x, y = p.y;
            if (visited[getId(x, y)]) {
                return;
            }
            
            visited[getId(x, y)] = true;
            group++;
            
            if (x > 0 && visited[getId(x - 1, y)]) {
                union(getId(x, y), getId(x - 1, y));
            }
            if (x < rows - 1 && visited[getId(x + 1, y)]) {
                union(getId(x, y), getId(x + 1, y));
            }
            if (y > 0 && visited[getId(x, y - 1)]) {
                union(getId(x, y), getId(x, y - 1));
            }
            if (y < cols - 1 && visited[getId(x, y + 1)]) {
                union(getId(x, y), getId(x, y + 1));
            }
        }
        
    	// 將二維座標映射到一維去
        private int getId(int x, int y) {
            return cols * x + y;
        }
        
        public int getGroup() {
            return group;
        }
    }
    
    /**
     * @param n:         An integer
     * @param m:         An integer
     * @param operators: an array of point
     * @return: an integer array
     */
    public List<Integer> numIslands2(int n, int m, Point[] operators) {
        // write your code here
        List<Integer> res = new ArrayList<>();
        
        if (operators == null || operators.length == 0) {
            return res;
        }
        
        UnionFind uf = new UnionFind(n * m, n, m);
    
        for (Point operator : operators) {
            uf.add(operator);
            res.add(uf.getGroup());
        }
        
        return res;
    }
}

class Point {
    int x, y;
    
    Point() {
        x = y = 0;
    }
    
    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

時間複雜度O(klogk)O(k\log k)kk爲操作次數),空間複雜度O(mn)O(mn)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章