zoukankan      html  css  js  c++  java
  • 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反而用了很久。。以后一定要多多小心,仔细答题!

  • 相关阅读:
    高精度计算
    高精度除以低精度
    P1258 小车问题
    POJ 2352 stars (树状数组入门经典!!!)
    HDU 3635 Dragon Balls(超级经典的带权并查集!!!新手入门)
    HDU 3938 Portal (离线并查集,此题思路很强!!!,得到所谓的距离很巧妙)
    POJ 1703 Find them, Catch them(确定元素归属集合的并查集)
    HDU Virtual Friends(超级经典的带权并查集)
    HDU 3047 Zjnu Stadium(带权并查集,难想到)
    HDU 3038 How Many Answers Are Wrong(带权并查集,真的很难想到是个并查集!!!)
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/8721096.html
Copyright © 2011-2022 走看看