LeetCode第[79]題(Java):Word Search(矩陣單詞搜尋)

來源:互聯網
上載者:User

標籤:als   nbsp   最好   cal   sub   正確答案   有一個   遞迴   題目   

題目:矩陣單詞搜尋

難度:Medium

題目內容

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

翻譯

給定一個2D的字元數組和一個單詞,找出這個詞是否存在於網格中。

這個詞可以用順序相鄰的細胞的字母來構造,在那裡“相鄰”的細胞是水平的或垂直的相鄰的。同一個字母單元可能不止一次使用。

Example:

board =[  [‘A‘,‘B‘,‘C‘,‘E‘],  [‘S‘,‘F‘,‘C‘,‘S‘],  [‘A‘,‘D‘,‘E‘,‘E‘]]Given word = "ABCCED", return true.Given word = "SEE", return true.Given word = "ABCB", return false.

我的思路:對整個二維數組進行迴圈,對於每一個字母都進入遞迴方法,

1、判斷當前字元如果不與傳入字串第一個字母匹配,或者訪問過則返回fasle;

2、這是最後一個字元,返回true;(已經通過上面的判斷已經是匹配的)

3、將此位置的訪問符置1,然後分別向上、下、左、右四個方向調用遞迴方法;

4、四個方向訪問完畢,說明由此處開始的路徑已經有結果,將此位置訪問符再置0,並返回四個方向的“或”。

為什麼又要再置0?

  因為整個遞迴過程就只有一個used訪問標誌矩陣(參考型別),如果每次訪問後就設定1,不再管,那麼之前已經失敗的路徑就會對之後再訪問的路徑(對於此路徑是新訪問的)產生影響。

此處的訪問符類 used 似於第[47]題Permutations 2  中的used使用方法是一樣的,不過意義不同,

所以,若在遞迴中有包含訪問符,調用遞迴結束後,訪問符應該置0(或false)

 

My Code:

 1     public boolean exist(char[][] board, String word) { 2         for (int i = 0; i < board.length; i++) { 3             for (int j = 0; j < board[0].length; j++) { 4                 if (find(word, i, j, board, new int[board.length][board[0].length])) { 5                     return true; 6                 } 7             } 8         } 9         return false;10     }11     12     private boolean find(String word, int i, int j, char[][] board, int[][] used) {13         if (i < 0 || i > board.length-1 || j < 0 || j > board[0].length-1) {14             return false;15         }16         if (board[i][j] != word.charAt(0) || used[i][j] == 1) {17             return false;18         } else if (word.length() == 1) {19             return true;20         }21         used[i][j] = 1;22         boolean ans = find(word.substring(1), i-1, j, board, used) 23                 || find(word.substring(1), i+1, j, board, used)24                 || find(word.substring(1), i, j-1, board, used)25                 || find(word.substring(1), i, j+1, board, used);26         used[i][j] = 0;27         return ans;28     }

我的複雜度:O((m*n)2)

編碼過程中的問題

1、之前採用的是先判斷首字母是匹配然後直接返回find方法的結果,後來發現這樣做是不行的,因為如果在正確答案的前面如果有一個是前面匹配後面不匹配的錯誤答案,就會直接返回錯誤答案的false;——————如果  true  則return true,否則繼續

2、之前沒考慮到標誌位,從而路徑會往回找;“【【a,a】】”  “aaa”

3、之前是用了四個標誌位“up-down-left-right”,每次都判斷是否能上下左右再進行遞迴調用,如下:

        if (i > 0) {            up = find(word.substring(1), i-1, j, board, used);        }

  然後最後再對這四個標誌位進行 或 運算,但是這樣做路徑中的字母每次都會進行四個遞迴,沒有短路的可能,所以當需要方法多分支遞迴的時候,最好改成直接調用方法進行  短路與或   運算, 然後在方法的開頭加入此結果的判斷,這樣能減少不少多餘的運算。【本題將是否能上下左右的判斷加入到了遞迴方法的最開始】

4、本方法其實還可以最佳化,就是將訪問過的字元用“*”表示,在遞迴結束後再設定成原來的值,這樣就可以省去建立一個標誌矩陣。

 

答案代碼

 1 public boolean exist(char[][] board, String word) { 2     char[] w = word.toCharArray(); 3     for (int y=0; y<board.length; y++) { 4         for (int x=0; x<board[y].length; x++) { 5             if (exist(board, y, x, w, 0)) return true; 6         } 7     } 8     return false; 9 }10 11 private boolean exist(char[][] board, int y, int x, char[] word, int i) {12     if (i == word.length) return true;13     if (y<0 || x<0 || y == board.length || x == board[y].length) return false;14     if (board[y][x] != word[i]) return false;15     board[y][x] ^= 256;16     boolean exist = exist(board, y, x+1, word, i+1)17         || exist(board, y, x-1, word, i+1)18         || exist(board, y+1, x, word, i+1)19         || exist(board, y-1, x, word, i+1);20     board[y][x] ^= 256;21     return exist;22 }

答案思路

基本思路是一樣的,不過有兩個亮點是比我的方法好的:

1、利用char[] 和 一個 int 表示當前所在第幾個字母,代替了頻繁利用subString來建立一個字串;

2、利用二進位運算  與或  的特性——與或全1,再與或全1就會等於自己,因為說好都是字母,而且字母為65~90,95~122內,所以與或128也是可以的。從而不必再用temp了。

 

LeetCode第[79]題(Java):Word Search(矩陣單詞搜尋)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.