UnionFInd-----130. Surrounded Regions

原题目

着色法,把陆地圈出来然后再做遍历。但是出现了栈溢出的情况。

1.栈溢出


import java.util.ArrayList;
import java.util.List;

/**
 * Created by XQF on 2017/8/11.
 */

class ListNode {
    int val;
    ListNode next;

    public ListNode(int a) {
        this.val = a;
    }
}

class Point {
    int x;
    int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return x + " " + y + "\n";
    }
}


public class Solution {
    private int[][] next = {
            {0, 1},
            {1, 0},
            {0, -1},
            {-1, 0}
    };

    public void solve(char[][] board) {
        if (board == null || board.length == 0) {
            return;
        }
        int len1 = board.length;
        int len2 = board[0].length;
        int[][] book = new int[len1][len2];
        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < len2; j++) {
                book[i][j] = 0;
            }
        }
        List<List<Point>> points = new ArrayList<>();
        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < len2; j++) {
                if (board[i][j] == 'O' && book[i][j] != 1) {
                    List<Point> temp = new ArrayList<>();
                    book[i][j] = 1;
                    Point p = new Point(i, j);
                    temp.add(p);
                    dfs(board, book, i, j, temp);
                    points.add(temp);
                }
            }
        }

        for (List<Point> list : points) {
            if (isSurranded(list, len1, len2)) {
                help(list, board);
            }
        }
    }

    private void dfs(char[][] board, int[][] book, int i, int j, List<Point> temp) {
        int len1 = board.length;
        int len2 = board[0].length;
        for (int k = 0; k <= 3; k++) {
            int x = i + next[k][0];
            int y = j + next[k][1];
            if (x < 0 || x >= len1 || y < 0 || y >= len2) {
                continue;
            }
            if (board[x][y] == 'O' && book[x][y] == 0) {
                book[x][y] = 1;
                Point p = new Point(x, y);
                temp.add(p);
                dfs(board, book, x, y, temp);
            }
        }
    }

    public boolean isSurranded(List<Point> list, int x, int y) {
        boolean result = true;
        for (int i = 0; i < list.size(); i++) {
            Point p = list.get(i);
            if (p.x + 1 >= x || p.y + 1 >= y) {
                result = false;
                break;
            }
            if (p.x - 1 < 0 || p.y - 1 < 0) {
                result = false;
                break;
            }
        }
        return result;
    }

    public void help(List<Point> list, char[][] board) {

        for (Point p : list) {
            int x = p.x;
            int y = p.y;
            board[x][y] = 'X';
        }

    }


    public void print(char[][] board) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();

        char[][] board = new char[][]{
                {'X', 'O', 'X', 'X'},
                {'X', 'O', 'O', 'X'},
                {'X', 'X', 'O', 'X'},
                {'X', 'O', 'X', 'X'},
        };

        solution.solve(board);
        solution.print(board);
    }

}

2.队列

参考了别人的思路

既然说我栈溢出,那我就不用栈我用队列哈哈。使用宽度优先。但是为了减少搜索的次数,根据题目意思进行简单的改变而不是全部搜索(将道理要是深搜也这样优化应该也是能通过的)。我们只需要根据四个边的情况来搜索,一旦出现‘O‘进行扩展并做好标记。这样就好做多了

 public int[][] next = new int[][]{
            {1, 0},
            {0, -1},
            {-1, 0},
            {0, 1}
    };


    public void solve(char[][] board) {
        if (board == null || board.length == 0) {
            return;
        }
        int len1 = board.length;
        int len2 = board[0].length;
        int[][] book = new int[len1][len2];

        for (int i = 0; i < len1; i++) {
            bfs(board, book, i, 0);
            bfs(board, book, i, len2 - 1);
        }

        for (int i = 0; i < len2; i++) {
            bfs(board, book, 0, i);
            bfs(board, book, len1 - 1, i);
        }

        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < len2; j++) {
                if (board[i][j] == 'O') {
                    board[i][j] = 'X';
                } else if (board[i][j] == '#') {
                    board[i][j] = 'O';
                }
            }
        }

    }

    private void bfs(char[][] board, int[][] book, int i, int j) {
        if (board[i][j] != 'O') {
            return;
        }
        int len1 = board.length;
        int len2 = board[0].length;
        Queue q = new LinkedList<>();
        board[i][j] = '#';
        q.add(new Point(i, j));
        while (!q.isEmpty()) {
            Point p = (Point) q.poll();
            int x = p.x;
            int y = p.y;
            for (int k = 0; k <= 3; k++) {
                int xx = x + next[k][0];
                int yy = y + next[k][1];
                if (xx < 0 || xx >= len1 || yy < 0 || yy >= len2) {
                    continue;
                }
                if (board[xx][yy] == 'O' && book[xx][yy] == 0) {
                    book[xx][yy] = 1;
                    board[xx][yy] = '#';
                    q.add(new Point(xx, yy));
                }
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值