import java.util.*; /** * Given a matrix with each grid a color type. Start from a random point, find * the perimeter of the region of the same color. * * Tags: BFS */ class MatrixColor { public static void main(String[] args) { MatrixColor m = new MatrixColor(); int[][] mat = { {2, 2, 1, 2}, {2, 2, 1, 2}, {2, 1, 1, 2}, {2, 2, 1, 2}, }; System.out.println(m.findPerimeter(mat, 0, 2)); System.out.println(m.findPerimeter(mat, 0, 1)); System.out.println(m.findPerimeter(mat, 0, 3)); } /** * BFS * addRecursive the start point to a queue, and set it as visited * Convert 2d coordinate to 1d integer and store it in queue * While the queue is not empty, get an integer from the queue * Convert it back to 2d and search the 4 cells around it * If within board, and not visited, add it to queue and set visited * If not same color, add edge count * If not within board, add edge count */ public int findPerimeter(int[][] mat, int x, int y) { if (mat == null || mat.length == 0 || mat[0].length == 0) return 0; Queue<Integer> q = new LinkedList<Integer>(); int m = mat.length; int n = mat[0].length; boolean[][] visited = new boolean[m][n]; int[][] dir = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; q.add(x * n + y); visited[x][y] = true; int perimeter = 0; while (!q.isEmpty()) { int size = q.size(); for (int i = 0; i < size; i++) { int pos = q.poll(); int curX = pos / n; int curY = pos % n; // update perimeter // System.out.println("curX: " + curX + " curY: " + curY); int count = 0; for (int[] d : dir) { int nX = curX + d[0]; int nY = curY + d[1]; if (nX >= 0 && nX < m && nY >= 0 && nY < n) { if (mat[nX][nY] == mat[x][y]) { if (!visited[nX][nY]) { q.add(nX * n + nY); visited[nX][nY] = true; } } else count++; } else count++; } perimeter += count; // System.out.println("count: " + count + " p: " + perimeter); } } return perimeter; } }