题目连接
题目大意:类似于围棋,把被X围着的O都变为X。注意如果O的上下左右之一在边界不算围着,那么久不改变。
直观的思路是:dfs(数据量太大爆栈了)或者bfs.
import java.util.*;
public class Solution {
//dfs 从图中一个O开始遍历相连的所有O
HashSet<Integer> visited = new HashSet<Integer>();
ArrayList<Integer> arrayList = new ArrayList<Integer>();
int maxPoints = 1000;
int M,N;
char[][] map = new char[maxPoints][maxPoints];
// public void solve(char[][] grap){
// if(grap==null || grap.length==0 || grap[0].length==0){
// return ;
// }
// M = grap.length;
// N = grap[0].length;
// //第一列和最后一列
// for(int i=0;i<M;i++){
// dfs(i, 0, M, N, grap);
// if(N-1!=0){
// dfs(i,N-1,M,N,grap);
// }
// }
// //第一行和最后一行
// for(int i=0;i<N;i++){
// dfs(0, i, M, N, grap);
// if(M-1!=0){
// dfs(M-1, i, M, N, grap);
// }
// }
// //将所有为更改的O改为X
// for(int i=0;i<M;i++){
// for(int j=0;j<N;j++){
// if(grap[i][j]=='O'){
// grap[i][j] ='X';
// }
// }
// }
// //将所有剩余的P改为O
// for(int i=0;i<M;i++){
// for(int j=0;j<N;j++){
// if(grap[i][j]=='P'){
// grap[i][j] ='O';
// }
// }
// }
// }
public void solve(char[][] grap){
if(grap==null || grap.length==0 || grap[0].length==0){
return ;
}
//初始化一个图
initMap(grap);
//遍历每一个未访问过的O节点
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
int value = getValue(i, j,M, N);
if(visited.contains(value)){
continue;
}
if(grap[i][j]=='X' ){
//什么都不做
visited.add(value);
}else{//为O
//arrayList.clear();
//搜索得到相连的所有O
arrayList.clear();
bfs(i,j,M,N);
boolean flag = false;
for(int k=0;k<arrayList.size();k++){
int kValue = arrayList.get(k);
int row = getRow(M, N, kValue);
int col = getCol(M, N, kValue);
visited.add(kValue);
if(isAroundOut(row, col, M, N)){
flag = true;
}
}
//说明没有越界的O 都变为X
if(!flag){
for(int k=0;k<arrayList.size();k++){
int chileValue = arrayList.get(k);
int row = getRow(M, N, chileValue);
int col = getCol(M, N, chileValue);
grap[row][col] = 'X';
}
}
}
}
}
}
public boolean isAroundOut(int i,int j,int M,int N){
if((i-1<0)|| (i+1>=M) || (j-1<0) || (j+1>=N)){
return true;
}
return false;
}
//广度优先遍历从O开始相连的所有O
public void bfs(int i,int j,int M,int N){
Queue<Integer> queue = new LinkedList<Integer>();
int value = getValue(i, j, M, N);
int row,col;
queue.add(value);
visited.add(value);
while(!queue.isEmpty()){
value = queue.poll();
row = getRow(M, N, value);
col = getCol(M, N, value);
visited.add(value);
arrayList.add(value);
if(!isOut(row-1, col, M, N)&& map[row-1][col] =='O'){
int valueChild = getValue(row-1, col, M, N);
if(!visited.contains(valueChild)){
visited.add(valueChild);
queue.add(valueChild);
}
}
if(!isOut(row+1, col, M, N)&& map[row+1][col] =='O'){
int valueChild = getValue(row+1, col, M, N);
if(!visited.contains(valueChild)){
visited.add(valueChild);
queue.add(valueChild);
}
}
if(!isOut(row, col-1, M, N)&& map[row][col-1] =='O'){
int valueChild = getValue(row, col-1, M, N);
if(!visited.contains(valueChild)){
visited.add(valueChild);
queue.add(valueChild);
}
}
if(!isOut(row, col+1, M, N) && map[row][col+1] =='O'){
int valueChild = getValue(row, col+1, M, N);
if(!visited.contains(valueChild)){
visited.add(valueChild);
queue.add(valueChild);
}
}
}
}
public boolean isOut(int i,int j,int M,int N){//判断某一个点是否出界
if(i<0 || i>=M || j<0 || j>=N){
return true;
}
return false;
}
//把所有从O开始相连的O都变为X
public void dfs(int i,int j,int M,int N,char[][] grap){
if(i<0 || i>=M || j<0 || j>=N){//越界
return;
}
if(grap[i][j]=='O'){
grap[i][j] = 'P';
dfs(i-1, j, M, N, grap);
dfs(i+1, j, M, N, grap);
dfs(i, j-1, M, N, grap);
dfs(i, j+1, M, N, grap);
}
}
// public void dfs(int i,int j,int M,int N){
// if(i<0 || i>=M || j<0 || j>=N){//越界
// return;
// }
// int value = getValue(i, j, M, N);
// if(visited.contains(value)){
// return ;
// }
// visited.add(value);
// if(map[i][j]=='O'){
// //加入列表中
// arrayList.add(value);
// //搜索四个方向
// dfs(i-1, j, M, N);
// dfs(i+1, j, M, N);
// dfs(i, j-1, M, N);
// dfs(i, j+1, M, N);
// }
//
// }
public void printArrayList(){
for(int i=0;i<arrayList.size();i++){
int value = arrayList.get(i);
int row = getRow(M, N, value);
int col = getCol(M, N, value);
System.out.println(row + " # " + col);
}
}
public void initMap(char[][] grap){
M =grap.length;
N = grap[0].length;
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
map[i][j] = grap[i][j];
}
}
}
public int getValue(int i,int j,int M,int N){
return (i)*N +j;
}
public int getRow(int M,int N,int value){
return value/N;
}
public int getCol(int M,int N,int value){
return value%N;
}
}
判断一个O群是否需要更改为X的条件是,O群中如果不存在周围出界的或者不存在四个边上的那么就全部更改为X否则不改
把所有的P改为O
代码在上面代码注释的solve中