<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    小明思考

    Just a software engineer
    posts - 124, comments - 36, trackbacks - 0, articles - 0
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    包圍的區(qū)域

    Posted on 2013-04-15 18:17 小明 閱讀(1560) 評(píng)論(2)  編輯  收藏 所屬分類(lèi): 數(shù)據(jù)結(jié)構(gòu)和算法
    問(wèn)題給定一個(gè)2D的棋盤(pán),含有‘X'和’O',找到所有被‘X'包圍的’O',然后把該區(qū)域的‘O’都變成'X'。

    例子-輸入:
    X X X X
    X O O X
    X X O X
    X O X X

    應(yīng)該輸出:

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

    public void solve(char[][] board) {
    }

    分析:
    為了提高效率,我使用了一個(gè)mark數(shù)組來(lái)記錄所有訪問(wèn)過(guò)的‘O'點(diǎn),避免重復(fù)檢查,同時(shí)要避免死循環(huán)。
    每個(gè)點(diǎn)有四種狀態(tài),未檢測(cè)(0),正在檢測(cè)(-1),包圍的點(diǎn)(1),沒(méi)有被包圍的點(diǎn)(2)。
    另外,為了對(duì)付很大的棋盤(pán),避免使用遞歸而造成堆棧溢出,使用了一個(gè)檢測(cè)隊(duì)列。

    代碼如下:

    public class SurroundedRegions {
        
        private char[][] board;
        private int[][] mark;
        private int h;
        private int w;
        
        private final int S = 1; //surrounded point
        private final int NS = 2; //Not surrounded point
        private final int T = -1; //testing point, undetermined point
        
        private static class Point{
            int x,y;
            
            Point(int x,int y){
                this.x =x;
                this.y = y;
            }
        }
        
        private int test(int i,int j, List<Point> lp){
            int result = S;
            mark[i][j] = T; 
            if(i==0 || i==h-1 || j==0 || j==w-1){ //border point
                result = NS;
            }
            else{
                int[] nx={i-1,i,i,i+1};
                int[] ny={j,j-1,j+1,j};
                for(int k=0;k<4;++k){ //check the four directions
                    int x = nx[k];
                    int y = ny[k];
                    if(board[x][y]=='O'){
                        int m = mark[x][y];
                        if(m==0){
                            mark[x][y] = T; //mark as testing point to avoid duplicated visit
                            lp.add(new Point(x,y));
                        }
                        else if(m>0){
                            result =  m;
                        }
                    }
                    if(result==NS){
                        break;
                    }
                }
            }
            mark[i][j]= result;
            return result;
        }
        
        public void solve(char[][] board) {
            this.h = board.length;
            if(h<1){
                return;
            }
            this.w = board[0].length;
            
            this.board = board;
            this.mark = new int[h][w];
            
            for(int i=0;i<h;++i){
                char[] row = board[i];
                int[] mrow = mark[i];
                for(int j=0;j<w;++j){
                    char c = row[j];
                    if(c=='O' && mrow[j]==0){ //not marked point
                        List<Point> lp = new ArrayList<Point>(); //visit queue
                        lp.add(new Point(i,j));
                        int result = S;
                        for(int k=0;k<lp.size();++k){ //Notice: the size of queue maybe increase during the loop  
                            Point p = lp.get(k);
                            if(test(p.x,p.y,lp) == NS){ //once find the NS flag,stop checking
                                result = NS;
                                break;
                            }
                        }
                        for(int k=0;k<lp.size();++k){ //mark  all points in the current visit queue
                            Point p = lp.get(k);
                            mark[p.x][p.y] = result;
                        }
                    }
                }
            }
            for(int i=0;i<h;++i){ //flip all marked points
                char[] row = board[i];
                int[] mrow = mark[i];
                for(int j=0;j<w;++j){
                    char c = row[j];
                    if(c=='O' && mrow[j]==S){
                        row[j] ='X';
                    }
                }
            }
        }

    ====update====
    改進(jìn)了一下,從邊開(kāi)始掃描,找到所有邊上白字相鄰的節(jié)點(diǎn)即可解決問(wèn)題。代碼如下:

    public class SurroundedRegions {

        private char[][] board;
        private int[][] mark;
        private int h;
        private int w;

        private static class Point {
            int x, y;

            Point(int x, int y) {
                this.x = x;
                this.y = y;
            }
        }

        private List<Point> extend(int i, int j) {
            List<Point> lp = new ArrayList<Point>();
            int[] nx = { i - 1, i, i, i + 1 };
            int[] ny = { j, j - 1, j + 1, j };
            for (int k = 0; k < 4; ++k) { // check the four directions
                int x = nx[k];
                int y = ny[k];
                if (x >= 0 && x < h && y >= 0 && y < w && board[x][y] == 'O' && mark[x][y] == 0) {
                    mark[x][y] = 1;
                    lp.add(new Point(x, y));
                }
            }
            return lp;
        }

        public void solve(char[][] board) {
            this.h = board.length;
            if (h <= 1) {
                return;
            }
            this.w = board[0].length;

            this.board = board;
            this.mark = new int[h][w];

            int x = 0, y = 0;
            int[] dxx = { 1, 0, -1, 0 };
            int[] dyy = { 0, 1, 0, -1 };

            for (int i = 0; i < 4; ++i) {
                int dx = dxx[i];
                int dy = dyy[i];
                int len = (i % 2 == 0) ? h : w;
                for (int j = 0; j < len-1; ++j) {
                    char c = board[x][y];
                    if (c == 'O' && mark[x][y] == 0) {
                        List<Point> vq = new ArrayList<Point>(); // visit queue
                        vq.add(new Point(x, y));
                        while (!vq.isEmpty()) {
                            Point p = vq.remove(vq.size() - 1);
                            mark[p.x][p.y] = 1;
                            vq.addAll(extend(p.x, p.y));
                        }
                    }
                    x += dx;
                    y += dy;
                }
            }

            for (int i = 0; i < h; ++i) { // flip all unmarked points
                char[] row = board[i];
                int[] mrow = mark[i];
                for (int j = 0; j < w; ++j) {
                    char c = row[j];
                    if (c == 'O' && mrow[j] == 0) {
                        row[j] = 'X';
                    }
                }
            }
        }
    }





    評(píng)論

    # re: 包圍的區(qū)域  回復(fù)  更多評(píng)論   

    2013-04-22 10:43 by cintana
    貌似太復(fù)雜了,為啥不直接掃描邊上的‘o'呢,一下就解決了。

    # re: 包圍的區(qū)域  回復(fù)  更多評(píng)論   

    2013-04-22 18:05 by 小明
    @cintana

    謝謝,確實(shí),我想復(fù)雜了
    主站蜘蛛池模板: 久视频精品免费观看99| 国产精品亚洲专区无码牛牛| 亚洲av手机在线观看| 99久久久国产精品免费蜜臀| 一级毛片a免费播放王色电影 | 亚洲中文字幕久久久一区| 成人人免费夜夜视频观看| 日本视频免费高清一本18| 四虎国产精品成人免费久久 | 成人免费视频一区二区| 2020国产精品亚洲综合网| 亚洲AV无码一区二区乱子伦| 久久久久久影院久久久久免费精品国产小说 | 岛国精品一区免费视频在线观看| 亚洲妇女无套内射精| 亚洲喷奶水中文字幕电影| 亚洲精品免费视频| 可以免费看黄的网站| 国产AV日韩A∨亚洲AV电影 | 最近中文字幕免费完整| 91视频免费观看高清观看完整| 男男黄GAY片免费网站WWW| 亚洲日韩国产欧美一区二区三区| 亚洲伊人成无码综合网| 免费国产不卡午夜福在线| 女人张腿给男人桶视频免费版| 思思re热免费精品视频66| 久久久久久曰本AV免费免费| 国产免费无码AV片在线观看不卡 | 黄页网站在线观看免费高清| 91香焦国产线观看看免费| 久久国产乱子精品免费女| 韩日电影在线播放免费版| 中国好声音第二季免费播放| 国产精品1024在线永久免费| 亚洲国产成人资源在线软件| 青青草原精品国产亚洲av| 亚洲综合久久1区2区3区| 国产精品亚洲高清一区二区| 亚洲成A人片在线观看中文| 亚洲精品无码你懂的网站|