305 Number Of Islands II

问题描述:

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.

解题思路:

可以使用union-find(并查集)来解决这道问题。

在本题中提供的为二维坐标,但并查集中多用一维数组,我们可以通过使用 idx = x * m + y 来唯一确定二维数组中的一个位置的一维表示方法。其中m为列数。

再插入每一个位置的时候,检查上下左右是否为岛屿,如果是,则需要合并岛屿。

代码:

**
 * Definition for a point.
 * class Point {
 *     int x;
 *     int y;
 *     Point() { x = 0; y = 0; }
 *     Point(int a, int b) { x = a; y = b; }
 * }
 */

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
        ArrayList<Integer> ret = new ArrayList<Integer>();
        
        if(operators == null || operators.length == 0)
            return ret;
        
        
        int count = 0;
        int[] parent = new int[n*m];
        int[][] direction = {{-1,0}, {1, 0},{0,-1},{0,1}};
        for(int i = 0; i < n*m; i++){
            parent[i] = -1;
        }
        for(int i = 0; i < operators.length; i++){
            
            Point curPoint = operators[i];
            int curID = calID(curPoint.x, curPoint.y, m);
            if(parent[curID] != -1){
                ret.add(count);
                continue;
            }
            count++;
            parent[curID] = curID;
            //check surrounds
            if(curPoint.x - 1 >= 0){
                int adjID = calID(curPoint.x-1, curPoint.y, m);
                if(parent[adjID] != -1){
                    count = union(parent, curID, adjID, count);
                }
            }
            if(curPoint.y - 1 >= 0){
                int adjID = calID(curPoint.x, curPoint.y-1, m);
                if(parent[adjID] != -1){
                    count = union(parent, curID, adjID, count);
                }
            }
            if(curPoint.x + 1 < n){
                int adjID = calID(curPoint.x + 1, curPoint.y, m);
                if(parent[adjID] != -1){
                    count = union(parent, curID, adjID, count);
                }
            }
            if(curPoint.y + 1 < m){
                int adjID = calID(curPoint.x, curPoint.y + 1, m);
                if(parent[adjID] != -1){
                    count = union(parent, curID, adjID, count);
                }
            }
            ret.add(count);
        }
        return ret;
    }
    
    private int calID(int i, int j, int row){
        return i*row + j;
    }
    
    private int find(int[] parent, int a){
        if(parent[a] == a){
            return a;
        } 
        return parent[a] = find(parent, parent[a]);
    }
    
    private int union(int[] parent, int a, int b, int count){
        int rootA = find(parent, a);
        int rootB = find(parent, b);
        if(rootA != rootB) {
            parent[rootB] = rootA;
            count--;
        }
        return count;
    }
}

其中,check surround中可以通过二维数组direction来进行检查

int[][] direction = {{-1,0}, {1, 0},{0,-1},{0,1}};

检查代码为:

for(int[] d : direction){
                int adjX = curPoint.x + d[0];
                int adjY = curPoint.y + d[1];
                
                int adjID = calID(adjX, adjY, m);
                
                if( adjX >= 0 && adjX < n 
                    &&adjY >= 0 && adjY < m && parent[adjID] != -1){
                        count = union(parent, curID, adjID, count);
                    }
            }

粗心出现过的bug _(:з」∠)_:

  1. 在计算唯一id:calID时,将x*m+y 算成了x*n+y, 导致了id不唯一 TAT
  2. 在周围检测时,在检查0的时候,用了<0而非<=0,导致边缘无法跳入代码块

做题用的时间不多,但是debug反而用了很久。。以后一定要多多小心,仔细答题!

原文地址:https://www.cnblogs.com/yaoyudadudu/p/8721096.html