给你一个目标字符串,和一个二维字符数组,判断在数组中是否能找到目标字符串。
例如,board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
算法思路
-
以每个单元格作为搜索起点,使用深度优先搜索(DFS)寻找可能匹配目标单词的路径
-
DFS实现要点:
- 终止条件:当匹配位置pos达到目标单词长度时,说明找到完整路径
- 搜索过程:从当前位置向四个方向扩展,检查边界条件并进行回溯
- 防重处理:在递归入口检查是否已访问,并验证当前字符是否匹配目标单词首字母
-
优化策略:
- 可行性剪枝:若目标单词中某字符出现频率超过board中的总数,直接终止
- 顺序优化:当目标单词尾字符出现频率低于首字符时,翻转单词可减少无效分支
class Solution { public: static constexpr int dx[4] = {0,0,-1,1},dy[4] = {-1,1,0,0}; bool dfs(int x,int y,int pos,string &word,int m,int n,vector<vector<char>>& board,vector<vector<int>>& vis) { if (pos == word.size()) { return true; } for (int i = 0;i < 4;i++) { int bx = dx[i] + x,by = dy[i] + y; if (bx < 0 || bx >= m || by < 0 || by >= n || board[bx][by] != word[pos] || vis[bx][by]) { continue; } vis[bx][by] = 1; if(dfs(bx,by,pos + 1,word,m,n,board,vis)) return true; vis[bx][by] = 0; } return false; } bool exist(vector<vector<char>>& board, string word) { int m = board.size(),n = board[0].size(); vector<vector<int>> vis(m,vector<int> (n,0)); unordered_map<char,int> bd_cnt; for (auto &row : board) { for (auto &p : row) { bd_cnt[p]++; } } unordered_map<char,int> word_cnt; if (word_cnt[word.back()] < word_cnt[word[0]]) { ranges::reverse(word); } for (auto &w : word) { if(++word_cnt[w] > bd_cnt[w]) return false; } for (int i = 0;i < m;i++) { for (int j = 0;j < n;j++) { if (board[i][j] == word[0]) { vis[i][j] = 1; if (dfs(i,j,1,word,m,n,board,vis)) { return true; }else{ vis[i][j] = 0; } } } } return false; } };
时间复杂度:O(mn3^4),m和n为行列数,对于每个入口最多有三个分支(因为上一个点已经搜索了一个方向),所以为O(mn3^4)
空间复杂度:O(1)