zoukankan      html  css  js  c++  java
  • 周围区域问题

    问题描述:

        给定二维平面,格点处要么是'X',要么是'O'。求出所有由'X'围成的区域。找到这样(多个)区域后,将所有的'O'转成'X'即可。如下图所示:

    X X X X

    X O O X

    X X O X 

    X O X X

    变为:

    X X X X

    X X X X

    X X X X

    X O X X

    思路分析:

     可以反向思考:哪些'O'应该是保留下来的呢?从边界开始搜索,如果中间的'O'可以跟边界处连通,则应该保留下来。那些在中间的'O'则应该变成'X'。

    做法:

    • 从四周的边缘处开始搜索,做广度优先遍历,对于碰到的'O',标记为其他的字符,证明已经遍历过;
    • 做完上面的广度优先搜索后,再遍历一遍整个地图,把所有的其他字符的地方恢复成"O",把仍是“O”的改成“X”即可。
    import java.util.LinkedList;
    import java.util.Queue;
    
    class Node {
        int x;
        int y;
        public Node(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    class Regions {
        private int[] rowdi = {-1, 1, 0, 0};
        private int[] coldi = {0, 0, -1, 1};
        
        /**
         * BFS. 
         * Search begin from the edge to the interior. 
         * @param val
         * @return
         */
        public int[][] check(int[][] val) {
            if(val == null || val.length == 0 || val[0].length == 0)
                return val;
            Queue<Node> q = new LinkedList<Node>();
            int row = val.length;
            int col = val[0].length;
            for(int i=0; i<row; i++) {
                if(val[i][0] == 0) {
                    Node n = new Node(i, 0);
                    q.add(n);
                    val[i][0] = 2;
                }
                if(val[i][col-1] == 0) {
                    Node n = new Node(i, col-1);
                    q.add(n);
                    val[i][col-1] = 2;
                }
            }
            for(int j=1; j<col-1; j++) {
                if(val[0][j] == 0) {
                    Node n = new Node(0, j);
                    q.add(n);
                    val[0][j] = 2;
                }
                if(val[row-1][j] == 0) {
                    Node n = new Node(row-1, j);
                    q.add(n);
                    val[row-1][j] = 2;
                }
            }
            while(!q.isEmpty()) {
                Node n = q.remove();
                for(int i=0; i<rowdi.length; i++) {
                    if( n.x+rowdi[i]<row && n.y+coldi[i] < col
                            && n.x+rowdi[i] >= 0 && n.y+coldi[i] >= 0) {
                        if(val[n.x+rowdi[i]][n.y+coldi[i]] == 0) {
                            Node t = new Node(n.x+rowdi[i], n.y+coldi[i]);
                            q.add(t);
                            val[n.x+rowdi[i]][n.y+coldi[i]] = 2;
                        }
                    }
                }
            }
            for(int i=0; i<row; i++) {
                for(int j=0; j<col; j++) {
                    if(val[i][j] == 2)
                        val[i][j] = 0;
                    else if(val[i][j] == 0)
                        val[i][j] = 1;
                }
            }
            return val;
        }
    }
    
    
    public class SurroundedRegions {
    
        public static void main(String[] args) {
            int[][] val = {
                    {1,1,1,1,1},
                    {1,0,0,1,0},
                    {1,1,1,1,0},
                    {1,0,1,0,0},
                    {1,1,1,1,1}};
            Regions region = new Regions();
            int[][] res = region.check(val);
            for(int i=0; i<res.length; i++) {
                for(int j=0; j<res[0].length; j++)
                    System.out.print(res[i][j] + " ");
                System.out.println();
            }
        }
    
    }

    思考:前面遇到一个围棋的题目,在求某个位置的气时,也是需要求周围区域,这样连通的海洋区域就相当于气是一样的,就赋值成相同的数字。当时思路比较混乱,现在做完这个题目后可以回头完成那个题目了~ 算法就是这样,是一种思路,当具备一定的编程能力时,思路就成了最重要的东西。关键是思路!

      

  • 相关阅读:
    OD调试1--第一个win32程序
    Koa与Node.js开发实战(1)——Koa安装搭建(视频演示)
    《11招玩转网络安全》之第五招:DVWA命令注入
    《11招玩转网络安全》之第四招:low级别的DVWA SQL注入
    一张图11招学会Python网络黑客
    《11招玩转网络安全》之第三招:Web暴力破解-Low级别
    《11招玩转网络安全》之第二招:漏洞扫描
    《11招玩转网络安全》之第一招:Docker For Docker
    11招玩转黑客攻防——用Python,更安全
    如何有效的练习并且提升写代码的能力?
  • 原文地址:https://www.cnblogs.com/little-YTMM/p/5480942.html
Copyright © 2011-2022 走看看