305. Number of Islands II

305. Number of Islands II

https://leetcode.com/problems/number-of-islands-ii/solution/


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


class Solution {
    public List<Integer> numIslands2(int m, int n, int[][] positions) {
        List<Integer> result = new ArrayList<>();
        int count = 0;
        UnionFind uf = new UnionFind(m*n); ///////
        int[][] matrix = new int[m][n]; /// the matrix is not given in the input
        int[][] directions = {{0,1},{0, -1},{-1, 0},{1, 0}}; // directions
        for(int[] position : positions){   /// new position, every sepaete island
            int i = position[0];
            int j = position[1];
            matrix[i][j] = 1; // in the matrix we just build, need to make this position as an island
            int key = getKey(i, j, n); // this is for the id, the parent id
            count++; // when new island comes in. later we do -- when union with separete islands 
            for(int[] direction : directions){ // every time a new island comes in, we see if unionable 
                int x = i + direction[0];
                int y = j + direction[1];
                if(x < 0 || y < 0 || x >= m || y >= n || matrix[x][y] == 0){ // this is def not unionable
                    continue;  // this is the first check for basic things like boundaries, if nei is island
                }else{
                    if(uf.union(key, getKey(x, y, n))){ // another check  to see if this island is connected already, if not connected yet, union it, and count--
                        count--;
                    }
                }
            }
            result.add(count); // after chekcing four directions of this new island, we are done this round
        }
        return result;
        
    }
    // now we need to code all the functions we used above in the main func
    public int getKey(int i, int j, int n){ // this is for its index in the array to look up parent id 
        return i * n + j;
    }
    
    // a separate class for union find 
    class UnionFind{
        int[] id; // this is for the parent id look up , to see if they belong to the same set
        
        
        public UnionFind(int n){ // this is a constructor, still dont know why use a constructor 
            this.id = new int[n]; // ???? first initalize the parent lookup array
            for(int i = 0; i < n; i++){
                id[i] = i; // this is to fill up the initnal parent, which is themselves 
            }
        }
        
        public int find(int i){ // find the ultimate parent, and also do path compression after finding the ulti root
            int root = i;      // need to keep the root for the path compression 
            while(root != id[root]){    // find the ultimate parent
                root = id[root];
            }
            
            while(id[i] != root){    // path compression after finding the ulti root
                int next = id[i];
                id[i] = root;
                i = next;
            }
            return root;
        }
        
        public boolean union(int p, int q){
            int rootp = find(p);
            int rootq = find(q);
            
            if(rootp == rootq){
                return false;
            }else{
                id[rootp] = rootq;
                return true;
            }
        }
        
    }
    
    
}

//  union by size 
      public boolean union(int p, int q){
        int rootP = find(p);
        int rootQ = find(q);
        if(rootP == rootQ){
          return false;
        }else{
          if(size[rootP] < size[rootQ]){
            id[rootP] = rootQ;
            size[rootQ] += size[rootP];
          }else{
            id[rootQ] = rootP;
            size[rootP] += size[rootQ];
          }
          return true;
        }
      }
      
    }
}

 

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.

Example:

Input: m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]]
Output: [1,1,2,3]

Explanation:

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

Follow up:

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

 

posted on 2018-08-09 18:09  猪猪&#128055;  阅读(124)  评论(0)    收藏  举报

导航