zoukankan      html  css  js  c++  java
  • [LeetCode] 130. Surrounded Regions Java

    题目:Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

    A region is captured by flipping all 'O's into 'X's in that surrounded region.

    For example,

    X X X X
    X O O X
    X X O X
    X O X X

    After running your function, the board should be:

    X X X X
    X X X X
    X X X X
    X O X X
     
    题意及分析:给出一个二位矩阵,若存在'O'组成的区域被‘X’包含,那么将改‘O’区域替换为‘X’。我最开始想到的是,用一个visited[row][col]保存该点是否访问过,然后遍历矩阵,对遇到的非边界、为访问过的‘O’点进行区域查找,将区域用一个List<Integer[]> 保存,若不存在在边界的‘O’,那么该区域满足条件(其实就是图的宽度查找),但是这里用了递归,所以运行代码栈溢出。。。反向思维:从边界的‘O’点开始查找,如果有何边界的‘O’点相连的则不用替换(这里用一个'#'先替换),遍历所有的边界‘O’,最后对遍历一次矩阵,将所有的'O'转化为‘X’,然后在遍历一次将‘#’转回为‘O’,这样可以直接替换,不需要保存可能的值。
    内存溢出代码:
    public class Solution {
        public void solve(char[][] board) {
            int row = board.length;     //行数
            if(row==0) return;
            int col=board[0].length;      //列数
            boolean[][] visited = new boolean[row][col];
            for(int i=0;i<row;i++){
                for(int j=0;j<col;j++){
                    List<Integer[]> union = new ArrayList<>();
                    if((i!=0&&j!=0&&i!=row-1&&j!=col-1)&&(board[i][j]=='O')&&(!visited[i][j])){     //遍历到非边界且未被访问过的'o'
                        union.clear();     // 遍历到一个未被访问的o点,就访问该点能到达的所有'o'点
                        boolean[] isNeedChange = {true};     //判断该'o'点能达到的区域是否满足要求
                        findUnion(visited,union,i,j,board,isNeedChange);
                        if(isNeedChange[0]){     //该区域需要改变,那就改变咯
                            for(int m=0;m<union.size();m++){
                                Integer[] temp = union.get(m);
                                board[temp[0]][temp[1]] = 'X';
                            }
                        }
                    }
                }
            }
        }
    
        public void findUnion(boolean[][] visited,List<Integer[]> union,int i,int j,char[][] board,boolean[] isNeedChange){     //查找某一个'o'区域
            int row = board.length;
            int col = board[0].length;
            if(visited[i][j]) return;           //该点已经访问过,直接返回
            visited[i][j] =true;
            Integer[] indexs = {i,j};
            if(isNeedChange[0]==false) {
                union.clear();
                return;
            }
            else {
                union.add(indexs);
            }
            if(i-1>=0&&board[i-1][j]=='O'){     //
                if(i-1==0) isNeedChange[0]=false;   //边界点有为'o'的
                findUnion(visited,union,i-1,j,board,isNeedChange);
            }
            if(i+1<row&&board[i+1][j]=='O'){     //
                if(i+1==row-1) isNeedChange[0]=false;   //边界点有为'o'的
                findUnion(visited,union,i+1,j,board,isNeedChange);
            }
            if(j-1>=0&&board[i][j-1]=='O'){     //
                if(j-1==0) isNeedChange[0]=false;   //边界点有为'o'的
                findUnion(visited,union,i,j-1,board,isNeedChange);
            }
            if(j+1<col&&board[i][j+1]=='O'){    //
                if(j+1==col-1) isNeedChange[0]=false;   //边界点有为'o'的
                findUnion(visited,union,i,j+1,board,isNeedChange);
            }
        }
    }

     AC代码:

    public class Solution {
        public void solve(char[][] board) {
            int row = board.length;     //行数
            if(row==0) return;
            int col=board[0].length;      //列数
            Queue<Integer[]> queue = new LinkedList<>();       //记录需要被替换的点,初始时是边界的点
            for(int i=0;i<col;i++){
                if(board[0][i]=='O') {      //上边界点为'O',宽度查找
                    Integer[] index={0,i};
                    queue.offer(index);
                }
            }
    
            for(int i=0;i<col;i++){
                if(board[row-1][i]=='O') {  //下边界有'O'
                    Integer[] index={row-1,i};
                    queue.offer(index);
                }
            }
    
            for(int i=1;i<row-1;i++){     //左边界点有’‘
                if(board[i][0]=='O') {
                    Integer[] index={i,0};
                    queue.offer(index);
                }
            }
            for(int i=1;i<row-1;i++){
                if(board[i][col-1]=='O') {
                    Integer[] index={i,col-1};
                    queue.offer(index);
                }
            }
            while(!queue.isEmpty()){
                Integer[] index = queue.poll();
                int m = index[0],n=index[1];
                if(board[m][n]=='O'){     //初次遍历到该点
                    board[m][n]='#';  //将该点置为'#'
                    if(m>=1&&board[m-1][n]=='O'){
                        Integer[] temp = {m-1,n};
                        queue.offer(temp);
                    }
                    if(m<row-1&&board[m+1][n]=='O'){
                        Integer[] temp = {m+1,n};
                        queue.offer(temp);
                    }
                    if(n>=1&&board[m][n-1]=='O'){
                        Integer[] temp = {m,n-1};
                        queue.offer(temp);
                    }
                    if(n<col-1&&board[m][n+1]=='O'){
                        Integer[] temp = {m,n+1};
                        queue.offer(temp);
                    }
                }
            }
            for(int i=0;i<row;i++){     //替换被包含的'O'点
                for (int j=0;j<col;j++){
                    if(board[i][j]=='O')
                        board[i][j]='X';
                }
            }
            for(int i=0;i<row;i++){     //替换回来
                for (int j=0;j<col;j++){
                    if(board[i][j]=='#')
                        board[i][j]='O';
                }
            }
            return;
        }
    }

     

  • 相关阅读:
    shell编程-项目部署(优化篇)
    数据库相关
    python基础面试
    scrapy爬取数据进行数据库存储和本地存储
    C# 对字符串操 替换数字 替换非数字 去除首尾字符 长沙
    还在为删除集合中的相同项而烦恼吗?
    C#之Task&匿名方法
    如何在火狐里面实现如下功能
    valueOf和toString曾经欺骗过你吗?
    JS 实现Json查询方法
  • 原文地址:https://www.cnblogs.com/271934Liao/p/7239411.html
Copyright © 2011-2022 走看看