原题大意:给定一个char的二维数组board(C++中用vector<vector<char> >实现) 和一个单词word,判断,在二维数组中是否存在一个串等于word,这个串可以是二维数组中任意相邻(上下左右)字符组成的串,但二维数组的每个元素只能被用一次。
例子:
board=[ ["ABCE"], ["SFCS"], ["ADEE"] ] word ="ABCCED"
, -> returnstrue
, word ="SEE"
, -> returnstrue
, word ="ABCB"
, -> returnsfalse
很明显是用搜索里的深度优先遍历方法,很快写出了代码:
class Solution { public: vector<vector<bool> >isUsed; bool exist(vector<vector<char> > &board, string word) { if(word.empty()) return true; if(board.empty()) return false; vector<bool> tmp; for(int m=0;m<board.size();m++) { tmp.clear(); tmp.resize(board[m].size(),false); isUsed.push_back(tmp); //cout<<m<<endl; } //cout<<board.size()<<":"<<isUsed.size()<<endl;system("pause"); for(int i=0;i<board.size();i++) for(int j=0;j<board[i].size();j++) { if(board[i][j]!=word[0]) continue; if(word.size()==1) return true;//注意word可能只有一个字符 isUsed[i][j]=true; if(i>0&&isExit(board,i-1,j,word,1))//up return true; if(i<board.size()-1&&isExit(board,i+1,j,word,1)) //down return true; if(j>0&& isExit(board,i,j-1,word,1))//left return true; if(j<board[i].size()-1&&isExit(board,i,j+1,word,1))//right return true; isUsed[i][j]=false; } return false; } bool isExit(vector<vector<char> >&board,int i,int j,string word,int k) { if(word.size()<=k) return true; if(board[i][j]!=word[k]||isUsed[i][j]==true)//可优化的地方 return false; isUsed[i][j]=true; if(i>0&&isExit(board,i-1,j,word,k+1))//up return true; if(i<board.size()-1&&isExit(board,i+1,j,word,k+1)) //down return true; if(j>0&& isExit(board,i,j-1,word,k+1))//left return true; if(j<board[i].size()-1&&isExit(board,i,j+1,word,k+1))//right return true; isUsed[i][j]=false; return false; } };
经过一次提交错误后,修改了下代码,再次提交后Accept。 本着优化代码,减少不必要的isExit递归调用,以减小运行时间,在调用isExit前提前判断isUsed[i][j]是否已被用过,修改的isExit方法为:
bool isExit(vector<vector<char> >&board,int i,int j,string word,int k)
{
if(word.size()<=k)
return true;
if(board[i][j]!=word[k])
return false;
isUsed[i][j]=true;
if(i>0&&isUsed[i-1][j]==false&&isExit(board,i-1,j,word,k+1))//up
return true;
if(i<board.size()-1&&isUsed[i+1][j]==false&&isExit(board,i+1,j,word,k+1)) //down
return true;
if(j>0&& isUsed[i][j-1]==false&&isExit(board,i,j-1,word,k+1))//left
return true;
if(j<board[i].size()-1&&isUsed[i][j+1]==false&&isExit(board,i,j+1,word,k+1))//right
return true;
isUsed[i][j]=false;
return false;
}
提交后提示超时,左思右想,不得其解,按理应该是会减小运行时间的,怎么还会超时呢? 回寝室后再看代码才发现 若isUsed[i-1][j]为false而K+1超过了word的size时,应该返回true的,但我的程序却忽略了K+1是否超过了word的size。加上该判断:
bool isExit(vector<vector<char> >&board,int i,int j,string word,int k)
{
if(word.size()<=k)
return true;
if(board[i][j]!=word[k]||isUsed[i][j]==true)
return false;
if(word.size()<=k+1)
return true;
isUsed[i][j]=true;
if(i>0&&isUsed[i-1][j]==false&&isExit(board,i-1,j,word,k+1))//up
return true;
if(i<board.size()-1&&isUsed[i+1][j]==false&&isExit(board,i+1,j,word,k+1)) //down
return true;
if(j>0&& isUsed[i][j-1]==false&&isExit(board,i,j-1,word,k+1))//left
return true;
if(j<board[i].size()-1&&isUsed[i][j+1]==false&&isExit(board,i,j+1,word,k+1))//right
return true;
isUsed[i][j]=false;
return false;
}
提交后通过,查看运行时间,毫无意外的缩短到了时间:160ms,(之前的是240ms)