活跃农民
- 积分
- 665
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2016-3-13
- 最后登录
- 1970-1-1
|
这是我的暴力解法,用union find减少可能的开始点,然后每个开始点都按照序列flip一遍看需要多少翻转多少次,然后取最小值。 时间和空间复杂度都是O(n^3),感觉不是很优,但是实在是想不出来了= =
- public class FlipColors {
- @Test
- public void test() {
- char[][] grid = new char[][] {
- {'r', 'g','g'},
- {'b', 'r', 'b'},
- {'b', 'r', 'g'}
- };
- // char[][] grid = new char[][] {
- // {'r', 'g','b','g','b','g','r'}
- // };
- /*
- * Asumption: the fliping order is fixed:
- * order = new char[] {'r', 'g', 'b'};
- * we can not flip r to b directly
- *
- * when we choose the start point, we can't change the point and flip other cells
- * m = rows, n = cols
- * Time: O((mn)^3)
- * Space: O((mn) ^ 3 )
- * */
- int res = findMinFlip(grid);
- System.out.println(res);
- }
- int[][] dirs = new int[][] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
- private char[] order = new char[] {'r', 'g', 'b'};
- /*
- * Main Procedure
- * */
- public int findMinFlip(char[][] grid) {
- int rows = grid.length;
- if(rows == 0) return 0;
- int cols = grid[0].length;
- if(cols == 0) return 0;
- // init unions
- Union union = new Union(rows * cols);
- // union cells with same color, to compress the start points
- for (int i = 0 ; i < rows ; i++) {
- for (int j = 0 ; j < cols ; j++) {
- for(int k = 0 ; k < dirs.length ; k++) {
- int x = i + dirs[k][0];
- int y = j + dirs[k][1];
- if(isValidate(grid, x, y) && grid[i][j] == grid[x][y]) {
- union.union(i * cols + j , x * cols + y);
- }
- }
- }
- }
- // pick up all the potential start points
- List<Integer> starts = new ArrayList<>();
- for(int i = 0 ; i < union.ids.length ; i++) {
- if(union.ids[i] == i) starts.add(i);
- }
- int res = Integer.MAX_VALUE;
- for(Integer start : starts) {
- char[][] copy = copyGraph(grid);
- int ans = getFlipNum(copy, start / cols, start % cols);
- if(ans < res) {
- res = ans;
- }
- }
- return res;
- }
- private char[][] copyGraph (char[][] grid) {
- char[][] copy = new char[grid.length][];
- for(int i = 0 ; i < grid.length ; i++) {
- copy[i] = Arrays.copyOfRange(grid[i], 0, grid[i].length);
- }
- return copy;
- }
- private int getFlipNum(char[][] grid, int row, int col) {
- int counter = 0;
- int rows = grid.length;
- int cols = grid[0].length;
- boolean flag = ifGetOneColor(grid); // whether we get the grid with one color
- while (!flag) {
- counter++;
- char prevColor = grid[row][col];
- grid[row][col] = getNextCol(grid[row][col]);
- boolean[][] visited = new boolean[rows][cols];
- flipNeighbor(grid, row, col, prevColor, grid[row][col], visited);
- flag = ifGetOneColor(grid);
- }
- return counter;
- }
- private void flipNeighbor(char[][] grid, int i, int j,
- char prevColor, char currColor, boolean[][] visited) {
- for(int k = 0 ; k < dirs.length ; k++) {
- int x = i + dirs[k][0];
- int y = j + dirs[k][1];
- if(isValidate(grid, x, y) && !visited[x][y] &&
- grid[x][y] == prevColor) {
- visited[x][y] = true;
- grid[x][y] = currColor;
- flipNeighbor(grid, x, y, prevColor, currColor, visited);
- }
- }
- }
- private boolean ifGetOneColor(char[][] grid) {
- char color = grid[0][0];
- for(int i = 0 ; i < grid.length ; i++) {
- for(int j = 0 ; j < grid[0].length ; j++) {
- if(grid[i][j] != color) {
- return false;
- }
- }
- }
- return true;
- }
- private char getNextCol(char curr) {
- int i = 0;
- for( ; i < order.length ; i++) {
- if(order[i] == curr) break;
- }
- if(i + 1 < order.length) return order[i + 1];
- else return order[0];
- }
- private boolean isValidate(char[][] grid, int i, int j) {
- return i < grid.length && i >= 0 && j >=0 && j < grid[0].length;
- }
- private class Union{
- int[] ids;
- int[] sizes;
- public Union(int len) {
- ids = new int[len];
- sizes = new int[len];
- for(int i = 0 ; i < ids.length ; i++) {
- ids[i] = i;
- sizes[i] = 1;
- }
- }
- public int find(int id) {
- if(ids[id] == id) return id;
- else {
- int root = find(ids[id]);
- // path compress
- ids[id] = root;
- return root;
- }
- }
- public void union(int id1, int id2) {
- int r1 = find(id1);
- int r2 = find(id2);
- if(r1 == r2) return ;
- else {
- ids[r2] = r1;
- sizes[r1] += sizes[r2];
- }
- }
- }
- }
复制代码 |
|