题目: 733. Flood Fill(https://leetcode.com/problems/flood-fill/description/)
解法1:
将符合条件的坐标放在一个队列里面,每次取一个(取完就在队列中移除),然后检查该坐标上下左右四个点中符合要求的坐标放进队列里,直到队列为空为止。
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
Queue<Location> queue = new LinkedList<>();
Location start = new Location(sr, sc);
queue.offer(start);
int old = image[sr][sc];
if(newColor == old) {
return image;
}
int rowLen = image.length;
int colLen = image[0].length;
while (!queue.isEmpty()) {
Location curr = queue.poll();
int currRow = curr.getRow();
int currCol = curr.getColumn();
image[currRow][currCol] = newColor;
Location up = new Location(currRow + 1, currCol);
Location down = new Location(currRow - 1, currCol);
Location left = new Location(currRow, currCol - 1);
Location right = new Location(currRow, currCol + 1);
if (currRow + 1 < rowLen && image[up.getRow()][up.getColumn()] == old) {
queue.offer(up);
}
if (currRow - 1 >= 0 && image[down.getRow()][down.getColumn()] == old) {
queue.offer(down);
}
if (currCol - 1 >= 0 && image[left.getRow()][left.getColumn()] == old) {
queue.offer(left);
}
if (currCol + 1 < colLen && image[right.getRow()][right.getColumn()] == old) {
queue.offer(right);
}
}
return image;
}
public static class Location {
private int row;
private int column;
public Location(int row, int column) {
this.row = row;
this.column = column;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Location location = (Location) o;
return row == location.row && column == location.column;
}
@Override
public int hashCode() {
return Objects.hash(row, column);
}
}
}
解法2:
使用Java的ForkJoinPool, 对于每个符合条件的点生成一个RecursiveAction,然后再在这个点的上下左右生成符合条件点的RecursiveAction。
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
ForkJoinPool pool = new ForkJoinPool();
RecursiveAction action = new FillAction(new Location(sr, sc), newColor, image);
pool.submit(action);
action.join();
pool.shutdown();
return image;
}
public static class Location {
private int row;
private int column;
public Location(int row, int column) {
this.row = row;
this.column = column;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
@Override
public String toString() {
return "Location [row=" + row + ", column=" + column + "]";
}
}
public static class FillAction extends RecursiveAction {
private Location location;
private int newColor;
private volatile int[][] image;
public FillAction(Location location, int newColor, int[][] image) {
this.location = location;
this.newColor = newColor;
this.image = image;
}
@Override
protected void compute() {
int rowLen = image.length;
int colLen = image[0].length;
int currRow = location.getRow();
int currCol = location.getColumn();
int old = image[currRow][currCol];
if (newColor == old) {
return;
}
image[currRow][currCol] = newColor;
Location up = new Location(currRow + 1, currCol);
Location down = new Location(currRow - 1, currCol);
Location left = new Location(currRow, currCol - 1);
Location right = new Location(currRow, currCol + 1);
List<RecursiveAction> actions = new ArrayList<>();
if (currRow + 1 < rowLen && image[up.getRow()][up.getColumn()] == old) {
RecursiveAction action = new FillAction(up, newColor, image);
action.fork();
actions.add(action);
}
if (currRow - 1 >= 0 && image[down.getRow()][down.getColumn()] == old) {
RecursiveAction action = new FillAction(down, newColor, image);
action.fork();
actions.add(action);
}
if (currCol - 1 >= 0 && image[left.getRow()][left.getColumn()] == old) {
RecursiveAction action = new FillAction(left, newColor, image);
action.fork();
actions.add(action);
}
if (currCol + 1 < colLen && image[right.getRow()][right.getColumn()] == old) {
RecursiveAction action = new FillAction(right, newColor, image);
action.fork();
actions.add(action);
}
for(RecursiveAction action: actions) {
action.join();
}
}
}
}