79. Word Search
題目給定一個 board 以及 一個 word ,我們要判斷的 board 上是否可以連線出 word。這題是蠻典型的 graph 類題目,用 BFS 或 DFS 解題都行,但用深度優先 DFS 來解題會比較好一些(可以先思考一下為什麼)。解題流程還蠻制式化的,是熟練 graph 類型的練習好題目 XD。
思路
為什麼使用 DFS 來解題會比較好一些呢 ?
以時間複雜度來說,BFS 或 DFS 相差不大,但空間複雜度 :
- BFS 會需要把相鄰所有可能的解部分,加到 queue 內
- DFS 是用遞迴,故是在 memory 中用 stack 來儲存 ; 若途中發現不對,就會返回上一層並 pop 掉。
故整體來說 DFS 來解題會比較好一些。並且題目有說, The same letter cell may not be used more than once ,故需要有防止遍歷重複走過位置。這邊可以想到要建立一個和 board 一樣大的 visited 2D-array,但其實也可以直接對 board 進行修改 (以下解題方式是將遍歷過的位置改為 0 ),但記得遞歸調用完後,需要恢復之前的狀態。
對其上下左右分別調用 DFS ,只要有一個返回 true,就表示找到了對應的字符串 (故以下解題方式是在 for-loop 內直接 return true)。
解答
class Solution {
int[][] directions = new int[][] {{1,0}, {-1,0}, {0,1}, {0,-1}};
public boolean exist(char[][] board, String word) {
for(int i = 0 ; i < board.length ; i++){
for(int j = 0 ; j < board[0].length ; j++){
if(dfs(board, i, j, 0, word)){
return true;
}
}
}
return false;
}
public boolean dfs(char[][] board, int i, int j, int index, String word){
if(index == word.length()){
return true;
}
if( i < 0 || i >= board.length ||
j < 0 || j >= board[0].length ||
word.charAt(index) != board[i][j]
){
return false;
}
char temp = board[i][j] ;
for(int[] direction : directions){
board[i][j] = '0';
int x = i + direction[0];
int y = j + direction[1];
if(dfs(board, x, y, index + 1, word)){
return true;
}
board[i][j] = temp;
}
return false;
}
}
對上下左右四個方向進行操作,故可以先定義 :
int[][] directions = new int[][] {{1,0}, {-1,0}, {0,1}, {0,-1}};
另外特別注意,是用 { , } 來表示 array。
Vocabulary
adjacent [əˋdʒesənt] : (d不發音,不要念錯了)
adj. 相鄰的,前後相接的
adjoin [əˋdʒɔɪn] : (d不發音,不要念錯了)
vt. 貼近,相連
example:
- New Jersey adjoins New York. 新澤西與紐約相連。