美文网首页
UnionFind count islands

UnionFind count islands

作者: Star_C | 来源:发表于2018-02-26 00:21 被阅读0次

    Question quoted from lintcode

    Given a n,m which means the row and column of the 2D matrix and an array of pair A( size k). Originally, the 2D matrix is all 0 which means there is only sea in the matrix. The list pair has k operator and each operator has two integer A[i].x, A[i].y means that you can change the grid matrix[A[i].x][A[i].y] from sea to island. Return how many island are there in the matrix after each operator.
    Example
    Given n = 3, m = 3, array of pair A = [(0,0),(0,1),(2,2),(2,1)].
    return [1,1,2,2].

    Idea: This is still a very typical UnionFind question. The trick is that you have to check and connect the neighbours by searching in the pairs. given that UnionFind uses a HashMap implementation, you can conduct the search efficiently by exposing some more methods at class UnionFind.

    /**
     * Definition for a point.
     * class Point {
     *     int x;
     *     int y;
     *     Point() { x = 0; y = 0; }
     *     Point(int a, int b) { x = a; y = b; }
     * }
     */
    
    class Cell {
        public final int rowNum;
        public final int colNum;
    
        public Cell(int rowNumber, int columnNumber) {
            this.rowNum = rowNumber;
            this.colNum = columnNumber;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            Cell cell = (Cell) o;
    
            if (rowNum != cell.rowNum) return false;
            return colNum == cell.colNum;
        }
    
        @Override
        public int hashCode() {
            int result = rowNum;
            result = 31 * result + colNum;
            return result;
        }
    
        public List<Cell> crossNeighbors() {
            LinkedList<Cell> neighbors = new LinkedList<>();
            neighbors.add(new Cell(rowNum -1, colNum));
            neighbors.add(new Cell(rowNum +1, colNum));
            neighbors.add(new Cell(rowNum, colNum+1));
            neighbors.add(new Cell(rowNum, colNum-1));
            return neighbors;
        }
    }
    
    class UnionFind<T> {
        private Map<T, T> rootMap = new HashMap<>();
        private int count = 0;
        private void ensureExist(T element) {
            if (!rootMap.containsKey(element)) {
                rootMap.put(element, element);
                count++;
            }
        }
        
        public T find(T x) {
            ensureExist(x);
            T root = rootMap.get(x);
            if (root.equals(x)) 
              return root;
            rootMap.put(x, find(root));
            return rootMap.get(x);
        }
        
        public boolean exists(T x) {
            return rootMap.containsKey(x);
        }
        
        public void add(T x) {
            ensureExist(x);
        }
        
        public void connect(T a, T b) {
            T rootA = find(a);
            T rootB = find(b);
            if (rootA.equals(rootB)) return;
            rootMap.put(rootA, rootB);
            count--;
        }
        
        public int groupCount() {
            return count;
        }
    }
    
    class Islands {
        private UnionFind<Cell> uf = new UnionFind();
        private int rowLen = 0;
        private int colLen = 0;
        public Islands(int n, int m) {
            rowLen = n;
            colLen = m;
        }
        public void add(Cell pos) {
            
            boolean inBound = pos.rowNum >= 0 && pos.rowNum < rowLen && pos.colNum >= 0 && pos.colNum < colLen;
            if (!inBound) return;
            
            uf.add(pos);
            for(Cell nei: pos.crossNeighbors()) {
                if (uf.exists(nei)) {
                    uf.connect(pos, nei);
                }
            }
        }
        public int count() {
            return uf.groupCount();
        }
    }
    
    public class Solution {
        /*
         * @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> result = new LinkedList<Integer>();
            
            if (operators == null) return result;
            
            if (operators.length == 0) return result;
            
            Islands islands = new Islands(n, m);
            for(Point p : operators) {
                Cell c = new Cell(p.x, p.y);
                islands.add(c);
                result.add(islands.count());
            }
            return result;
        }
        
    }
    

    相关文章

      网友评论

          本文标题:UnionFind count islands

          本文链接:https://www.haomeiwen.com/subject/nybdxftx.html