Surrounded Regions -- LeetCode
阿新 • • 發佈:2018-11-16
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
原題連結: http://oj.leetcode.com/problems/surrounded-regions/這個題目用到的方法是圖形學中的一個常用方法:
接下來我們看看這個題如何用 Flood fill演算法 來解決。首先根據題目要求,邊緣上的'O'是不需要填充的,所以我們的辦法是對上下左右邊緣做 Flood fill演算法 ,把所有邊緣上的'O'都替換成另一個字元,比如'#'。接下來我們知道除去被我們換成'#'的那些頂點,剩下的所有'O'都應該被替換成'X',而'#'那些最終應該是還原成'O',如此我們可以做最後一次遍歷,然後做相應的字元替換就可以了。複雜度分析上,我們先對邊緣做
public void solve (char[][] board) { if(board==null || board.length<=1 || board[0].length<=1) return; for(int i=0;i<board[0].length;i++) { fill(board,0,i); fill(board,board.length-1,i); } for(int i=0;i<board.length;i++) { fill(board,i,0); fill(board,i,board[0].length-1); } for(int i=0;i<board.length;i++) { for(int j=0;j<board[0].length;j++) { if(board[i][j]=='O') board[i][j]='X'; else if(board[i][j]=='#') board[i][j]='O'; } }}private void fill(char[][] board, int i, int j){ if(board[i][j]!='O') return; board[i][j] = '#'; LinkedList<Integer> queue = new LinkedList<Integer>(); int code = i*board[0].length+j; queue.offer(code); while(!queue.isEmpty()) { code = queue.poll(); int row = code/board[0].length; int col = code%board[0].length; if(row>0 && board[row-1][col]=='O') { queue.offer((row-1)*board[0].length+col); board[row-1][col]='#'; } if(row<board.length-1 && board[row+1][col]=='O') { queue.offer((row+1)*board[0].length+col); board[row+1][col]='#'; } if(col>0 && board[row][col-1]=='O') { queue.offer(row*board[0].length+col-1); board[row][col-1]='#'; } if(col<board[0].length-1 && board[row][col+1]=='O') { queue.offer(row*board[0].length+col+1); board[row][col+1]='#'; } }}
可以看到上面程式碼用的是廣度優先搜尋,用一個佇列來維護,當然也可以用深度優先搜尋,但是如果使用遞迴,會發現LeetCode過不了,這是因為在圖形中通常圖片(或者說這裡的矩陣)一般會很大,遞迴很容易導致棧溢位,所以即使要用深度優先搜尋,也最好使用非遞迴的實現方式哈。