surrounded-regions

题目

题目连接
surrounded-regions_第1张图片
题目大意:类似于围棋,把被X围着的O都变为X。注意如果O的上下左右之一在边界不算围着,那么久不改变。

思路1

直观的思路是:dfs(数据量太大爆栈了)或者bfs.

  1. 顺序搜索图中的每一个节点,并标记。
    对于每一个节点的处理
  2. 如果标记过则跳过
  3. 如果是X则标记跳过
  4. 如果是O则标记,并bfs所有相连的O存储到arrayList中
  5. 对于arrayList判断每一个数据是否周围是否是界,如果是界则标记最后什么都不做,如果没有发现节点周围是出界的则将所有节点改为X
    ## 代码 ##
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;
    }
}

思路2

判断一个O群是否需要更改为X的条件是,O群中如果不存在周围出界的或者不存在四个边上的那么就全部更改为X否则不改

  1. dfs(不会爆栈)或者bfs所有以O为边的群 ,这些节点代表不需要更改的O,那么剩下的O都要改为X
  2. 那么久在dfs的时候先把这些O改为P
  3. 搜索一遍把所有的O改为X
  4. 把所有的P改为O

    代码在上面代码注释的solve中

你可能感兴趣的:(bfs)