Go?Java算法之單詞搜索示例詳解
單詞搜索
給定一個 m x n 二維字符網(wǎng)格 board 和一個字符串單詞 word 。如果 word 存在于網(wǎng)格中,返回 true ;否則,返回 false 。
單詞必須按照字母順序,通過相鄰的單元格內(nèi)的字母構(gòu)成,其中“相鄰”單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內(nèi)的字母不允許被重復(fù)使用。
- 示例 1:
輸入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
輸出:true
- 示例 2:
輸入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
輸出:true
- 示例 3:
輸入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
輸出:false
提示:
- m == board.length
- n = board[i].length
- 1 <= m, n <= 6
- 1 <= word.length <= 15
board 和 word 僅由大小寫英文字母組成
算法:DFS回溯(Java)
- 以"SEE"為例,首先要選起點(diǎn):遍歷矩陣,找到起點(diǎn)S。
- 起點(diǎn)可能不止一個,基于其中一個S,看看能否找出剩下的"EE"路徑。
- 下一個字符E有四個可選點(diǎn):當(dāng)前點(diǎn)的上、下、左、右。
- 逐個嘗試每一種選擇?;诋?dāng)前選擇,為下一個字符選點(diǎn),又有四種選擇。
- 每到一個點(diǎn)做的事情是一樣的。DFS 往下選點(diǎn),構(gòu)建路徑。
- 當(dāng)發(fā)現(xiàn)某個選擇不對,不用繼續(xù)選下去了,結(jié)束當(dāng)前遞歸,考察別的選擇。
遞歸的關(guān)鍵點(diǎn)
- 關(guān)注當(dāng)前考察的點(diǎn),處理它,其他丟給遞歸子調(diào)用去做。
- 判斷當(dāng)前選擇的點(diǎn),本身是不是一個錯的點(diǎn)。
- 剩下的字符能否找到路徑,交給遞歸子調(diào)用去做。
- 如果當(dāng)前點(diǎn)是錯的,不用往下遞歸了,返回false。否則繼續(xù)遞歸四個方向,為剩下的字符選點(diǎn)。
那么,哪些情況說明這是一個錯的點(diǎn):
- 當(dāng)前的點(diǎn),越出矩陣邊界。
- 當(dāng)前的點(diǎn),之前訪問過,不滿足「同一個單元格內(nèi)的字母不允許被重復(fù)使用」。
- 當(dāng)前的點(diǎn),不是目標(biāo)點(diǎn),比如你想找 E,卻來到了 D。
class Solution { public boolean exist(char[][] board, String word) { if (board == null || board.length == 0) { return false; } boolean[][] visited = new boolean[board.length][board[0].length]; char[] chars = word.toCharArray(); for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { if (existHelper(board, visited, chars, i, j, 0)) { return true; } } } return false; } private boolean existHelper(char[][] board, boolean[][] visited, char[] chars, int row, int column, int index) { if (index == chars.length) { return true; } int[][] direction = new int[][]{ {0, 1}, {1, 0}, {0, -1}, {-1, 0} }; if (row >= 0 && row < board.length && column >= 0 && column < board[0].length && board[row][column] == chars[index] && !visited[row][column]) { visited[row][column] = true; for (int[] dir : direction) { int newX = row + dir[0]; int newY = column + dir[1]; if (existHelper(board, visited, chars, newX, newY, index + 1)) { return true; } } visited[row][column] = false; } return false; } }
時間復(fù)雜度:O(M*N * 3^L)
空間復(fù)雜度:O(M*N)
算法:DFS回溯(Go)
思路同上
func exist(board [][]byte, word string) bool { m, n := len(board), len(board[0]) used := make([][]bool, m) for i := 0; i < m; i++ { used[i] = make([]bool, n) } var canFind func(r, c, i int) bool canFind = func(r, c, i int) bool { if i == len(word) { return true } if r < 0 || r >= m || c < 0 || c >= n { return false } if used[r][c] || board[r][c] != word[i] { return false } used[r][c] = true canFindRest := canFind(r+1, c, i+1) || canFind(r-1, c, i+1) || canFind(r, c+1, i+1) || canFind(r, c-1, i+1) if canFindRest { return true } else { used[r][c] = false return false } } for i := 0; i < m; i++ { for j := 0; j < n; j++ { if board[i][j] == word[0] && canFind(i, j, 0) { return true } } } return false }
時間復(fù)雜度:O(M*N * 3^L)
空間復(fù)雜度:O(M*N)
以上就是Go Java算法之單詞搜索示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Go Java算法單詞搜索的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang實(shí)現(xiàn)深拷貝reflect原理示例探究
這篇文章主要為大家介紹了Golang實(shí)現(xiàn)reflect深拷貝原理示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01go數(shù)據(jù)結(jié)構(gòu)和算法BitMap原理及實(shí)現(xiàn)示例
這篇文章主要為大家介紹了go數(shù)據(jù)結(jié)構(gòu)和算法BitMap原理及實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07