努橙刷题编

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://leetcode.com/problems/surrounded-regions

weight union find 解法:

public class Solution {
    int[] id;
    int[] weight;
    int oRoot; // index of root of all 'O's connected to edge of the board
    public void solve(char[][] board) {
        if (board == null || board.length == 0 || board[0].length == 0) {
            return;
        }
        initUnionFind(board.length * board[0].length);
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (board[i][j] != 'O') {
                    continue;
                }
                int index = i * board[0].length + j;
                if (i == 0 || j == 0 || i == board.length - 1 || j == board[0].length - 1) {
                    union(index, oRoot); // connect the 'O' node on edge of the board with oRoot
                } else { // connect the node with 'O's around it
                    if (board[i + 1][j] == 'O') {
                        union(index, (i + 1) * board[0].length + j);
                    }
                    if (board[i - 1][j] == 'O') {
                        union(index, (i - 1) * board[0].length + j);
                    }
                    if (board[i][j - 1] == 'O') {
                        union(index, i * board[0].length + j - 1);
                    }
                    if (board[i][j + 1] == 'O') {
                        union(index, i * board[0].length + j + 1);
                    }
                }
            }
        }
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (board[i][j] == 'O' && find(i * board[0].length + j) != oRoot) {
                    board[i][j] = 'X';
                }
            }
        }
    }
    
    private void initUnionFind(int n) {
        oRoot = n;
        id = new int[n + 1];
        weight = new int[n + 1];
        for (int i = 0; i < n + 1; i++) {
            id[i] = i;
            weight[i] = 1;
        }
        weight[n] = n + 1; // make sure the value of oRoot is large enough
    }
    
    private void union(int i, int j) {
        int rootI = find(i);
        int rootJ = find(j);
        if (rootI == rootJ) {
            return;
        }
        if (weight[rootI] > weight[rootJ]) {
            id[rootJ] = rootI;
            weight[rootI] += weight[rootJ];
        } else {
            id[rootI] = rootJ;
            weight[rootJ] += weight[rootI];
        }
    }
    
    private int find(int i) {
        while (id[i] != i) {
            return find(id[i]);
        }
        return i;
    }
}

 

posted on 2017-05-22 23:52  努橙  阅读(141)  评论(0编辑  收藏  举报