Advertisement
1988coder

305. Number of Islands II

Jan 1st, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.61 KB | None | 0 0
  1. /**
  2.  * Using Union Find with ranks and path compression.
  3.  *
  4.  * Time Complexity: O(M*N + P). M*N to fill the arrays with -1. This can be
  5.  * minimized by increasing the parents and ranks array by 1. (Check solution
  6.  * below)
  7.  *
  8.  * Space Complexity: O(M*N)
  9.  *
  10.  * M = Number of rows, N = Number of columns, P = number of positions.
  11.  */
  12. class Solution {
  13.     class UnionFind {
  14.         int count;
  15.         int[] parents;
  16.         int[] ranks;
  17.  
  18.         UnionFind(int m, int n) {
  19.             count = 0;
  20.             parents = new int[m * n];
  21.             ranks = new int[m * n];
  22.             Arrays.fill(parents, -1);
  23.         }
  24.  
  25.         int findRoot(int pos) {
  26.             if (pos != parents[pos]) {
  27.                 parents[pos] = findRoot(parents[pos]);
  28.             }
  29.             return parents[pos];
  30.         }
  31.  
  32.         boolean isValidIsland(int pos) {
  33.             return parents[pos] >= 0;
  34.         }
  35.  
  36.         void setParent(int pos) {
  37.             parents[pos] = pos;
  38.             count++;
  39.         }
  40.  
  41.         void union(int x, int y) {
  42.             int pX = findRoot(x);
  43.             int pY = findRoot(y);
  44.  
  45.             if (pX == pY) {
  46.                 return;
  47.             }
  48.  
  49.             if (ranks[pX] >= ranks[pY]) {
  50.                 parents[pY] = pX;
  51.                 ranks[pX] = ranks[pX] == ranks[pY] ? ranks[pX] + 1 : ranks[pX];
  52.             } else {
  53.                 parents[pX] = pY;
  54.             }
  55.             count--;
  56.         }
  57.     }
  58.  
  59.     private static final int[][] dirs = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
  60.  
  61.     public List<Integer> numIslands2(int m, int n, int[][] positions) {
  62.         List<Integer> result = new ArrayList();
  63.         if (positions == null || positions.length == 0 || m <= 0 || n <= 0) {
  64.             return result;
  65.         }
  66.  
  67.         UnionFind uf = new UnionFind(m, n);
  68.  
  69.         for (int[] pos : positions) {
  70.             int curPos = pos[0] * n + pos[1];
  71.             uf.setParent(curPos);
  72.  
  73.             for (int[] dir : dirs) {
  74.                 int x = pos[0] + dir[0];
  75.                 int y = pos[1] + dir[1];
  76.                 int nextPos = x * n + y;
  77.                 if (x < 0 || y < 0 || x > m - 1 || y > n - 1 || !uf.isValidIsland(nextPos)) {
  78.                     continue;
  79.                 }
  80.                 uf.union(curPos, nextPos);
  81.             }
  82.  
  83.             result.add(uf.count);
  84.         }
  85.  
  86.         return result;
  87.     }
  88. }
  89.  
  90. /**
  91.  * Using Union Find with ranks and path compression.
  92.  *
  93.  * Time Complexity: O(P)
  94.  *
  95.  * Space Complexity: O(M*N)
  96.  *
  97.  * M = Number of rows, N = Number of columns, P = number of positions.
  98.  */
  99. class Solution {
  100.     class UnionFind {
  101.         int count;
  102.         int[] parents;
  103.         int[] ranks;
  104.  
  105.         UnionFind(int m, int n) {
  106.             count = 0;
  107.             parents = new int[m * n + 1];
  108.             ranks = new int[m * n + 1];
  109.         }
  110.  
  111.         int findRoot(int pos) {
  112.             if (pos != parents[pos]) {
  113.                 parents[pos] = findRoot(parents[pos]);
  114.             }
  115.             return parents[pos];
  116.         }
  117.  
  118.         boolean isValidIsland(int pos) {
  119.             return parents[pos] > 0;
  120.         }
  121.  
  122.         void setParent(int pos) {
  123.             parents[pos] = pos;
  124.             count++;
  125.         }
  126.  
  127.         void union(int x, int y) {
  128.             int pX = findRoot(x);
  129.             int pY = findRoot(y);
  130.  
  131.             if (pX == pY) {
  132.                 return;
  133.             }
  134.  
  135.             if (ranks[pX] >= ranks[pY]) {
  136.                 parents[pY] = pX;
  137.                 ranks[pX] = ranks[pX] == ranks[pY] ? ranks[pX] + 1 : ranks[pX];
  138.             } else {
  139.                 parents[pX] = pY;
  140.             }
  141.             count--;
  142.         }
  143.     }
  144.  
  145.     private static final int[][] dirs = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
  146.  
  147.     public List<Integer> numIslands2(int m, int n, int[][] positions) {
  148.         List<Integer> result = new ArrayList();
  149.         if (positions == null || positions.length == 0 || m <= 0 || n <= 0) {
  150.             return result;
  151.         }
  152.  
  153.         UnionFind uf = new UnionFind(m, n);
  154.  
  155.         for (int[] pos : positions) {
  156.             int curPos = pos[0] * n + pos[1] + 1;
  157.             uf.setParent(curPos);
  158.  
  159.             for (int[] dir : dirs) {
  160.                 int x = pos[0] + dir[0];
  161.                 int y = pos[1] + dir[1];
  162.                 int nextPos = x * n + y + 1;
  163.                 if (x < 0 || y < 0 || x > m - 1 || y > n - 1 || !uf.isValidIsland(nextPos)) {
  164.                     continue;
  165.                 }
  166.                 uf.union(curPos, nextPos);
  167.             }
  168.  
  169.             result.add(uf.count);
  170.         }
  171.  
  172.         return result;
  173.     }
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement