着色法,把陆地圈出来然后再做遍历。但是出现了栈溢出的情况。
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));
}
}
}
}