給定一個二維網格和一個單詞,找出該單詞是否存在于網格中,
單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中“相鄰”單元格是那些水平相鄰或垂直相鄰的單元格,同一個單元格內的字母不允許被重復使用,
示例:
board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]
給定 word = “ABCCED”, 回傳 true
給定 word = “SEE”, 回傳 true
給定 word = “ABCB”, 回傳 false
提示:
board 和 word 中只包含大寫和小寫英文字母,
1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3
解題思路:
這又是一道DFS應用題目,在搜索check函式中,首先看當前位置是不是你想要的字母,不是直接回傳false,是的話再確認一下是不是最后一個字母,是的話直接回傳true,如果不是最后一個字母,那么標記當前位置為訪問過,接著開始上下左右遍歷,定義一個vector<pair<int, int>>,{0,1},{0,-1},{-1,0},{1,0}代表著上下左右,for回圈遍歷這個vector,更新i,j,對其上下左右開始遍歷,如果接受到的flag為true,回傳并停止遍歷,最后注意要解除標記,否則會影響別的遍歷,代碼如下:
class Solution {
public:
bool check(vector<vector<char>>& board, vector<vector<int>>& visited, int i, int j, string& s, int k) {
//沒有該字母
if (board[i][j] != s[k]) {
return false;
} else if (k == s.length() - 1) {//正好到達最后一個單詞
return true;
}
visited[i][j] = true;//代表訪問過
vector<pair<int, int>> directions{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};//上下左右
bool result = false;
for (const auto& dir: directions) {
int newi = i + dir.first, newj = j + dir.second;
if (newi >= 0 && newi < board.size() && newj >= 0 && newj < board[0].size()) {//在輸入的二維網格范圍內
if (!visited[newi][newj]) {
bool flag = check(board, visited, newi, newj, s, k + 1);
if (flag) {
result = true;
break;
}
}
}
}
visited[i][j] = false;//一次訪問結束要取消標記
return result;
}
bool exist(vector<vector<char>>& board, string word) {
int h = board.size(), w = board[0].size();
vector<vector<int>> visited(h, vector<int>(w));//w*h的二維未標記網格
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
bool flag = check(board, visited, i, j, word, 0);
if (flag) {
return true;
}
}
}
return false;
}
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/38193.html
標籤:其他
下一篇:C#:屬性_賦值私有欄位
