// 超时代码 是粗鲁的暴力解决
class Solution {
public:
int n,m;
//标记是否被访问过
vector<vector<bool>> visit;
// idx(不包括)之前的都已经被访问过了
bool dfs(int i,int j,vector<vector<char>>& board, int idx, string word)
{
if(idx == word.size())
return true;
// 判断先决条件
if(i<0 || j<0 || i>=n || j>=m || visit[i][j] || word[idx]!=board[i][j])
return false;
visit[i][j]=true;
bool ret= dfs(i-1,j,board,idx+1,word) || dfs(i+1,j,board,idx+1,word) || dfs(i,j-1,board,idx+1,word) || dfs(i,j+1,board,idx+1,word);
visit[i][j] = false;
return ret;
}
bool exist(vector<vector<char>>& board, string word) {
for(int i=0; i<n; ++i)
{
for(int j=0; j<m; ++j)
{
if(dfs(i,j,board,0,word))
{
return true;
}
}
}
return false;
}
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
// 条件判断
vector<string> ret;
n= board.size();
if(n==0)
return ret;
m= board[0].size();
if (m==0)
return ret;
if(words.size()==0)
return ret;
visit.resize(n,vector<bool>(m, false));
set<string> sset;
for(int i=0; i<words.size();++i)
{
if(exist(board, words[i]) && sset.find(words[i])==sset.end())
sset.insert(words[i]);
}
auto it=sset.begin();
while(it!=sset.end())
{
ret.push_back(*it);
it++;
}
return ret;
}
};
//用字典树来实现AC
#include <string.h>
#include <memory.h>
class Solution {
public:
// 树的存储结构
struct TreeNode
{
TreeNode * child[26];
bool isWord;
TreeNode()
{
bzero(child, sizeof(child));
isWord = false;
}
};
vector<vector<char>> a;
vector<vector<bool>> use;
vector<string> ans;
int n;
int m;
const int wx[4] = {0,0,-1,1};
const int wy[4] = {1,-1,0,0};
void insert(TreeNode* r, const string word)
{
if(r==NULL) return ;
for(int i=0; i<word.size();++i)
{
int id = word[i]-'a';
if(r->child[id]==NULL)
{
r->child[id] = new TreeNode();
}
r = r->child[id];
}
r->isWord = true;
}
void visit(int x, int y, TreeNode *r, string s)
{
int id = a[x][y] - 'a';
if(r==NULL || r->child[id]==NULL) return;
// 找到的树中的分支
s = s+a[x][y];
use[x][y] = false;
// 开始word中的下一个字符。
r = r->child[id];
// 如果是一个单词,表明已经找到了
if(r->isWord)
{// find a word;
r->isWord =false;// 避免出现重复添加元素的现象
ans.push_back(s);
}
// 开始以x,y为中心往四个方向扩展
for(int i=0;i<4;++i)
{
int xx = x+wx[i];
int yy = y+wy[i];
if(xx>=0 && xx<n && yy>=0 && yy<m && use[xx][yy])// 边界条件判断
{
visit(xx, yy, r, s);// 递归下一个字符
}
}
use[x][y] = true;
}
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
ans.clear();
TreeNode* root = new TreeNode();
a = board;
n = a.size();
if(n==0) return ans;
m = a[0].size();
if(m==0) return ans;
use.resize(n, vector<bool>(m,true));
// build tree
for(int i=0; i<words.size(); ++i)
{
insert(root,words[i]);
}
// run 遍历每个格子中的点 会包含第一层所有出现的字符,根据这个字符开始递归进行处理。
for(int i=0;i<n;++i)
{
for(int j=0;j<m;++j)
{
visit(i,j,root,"");
}
}
return ans;
}
};