(1) Sudoku Solver
注意细节[1]:
class Solution {
private:
bool isValid(vector<vector<char> > &board, int x, int y)
{
int i, j;
for (i = 0; i < 9; i++)
if (i != x && board[i][y] == board[x][y])
return false;
for (j = 0; j < 9; j++)
if (j != y && board[x][j] == board[x][y])
return false;
int a=x/3*3;
int b=y/3*3;
for (i=0;i<3;i++)
for (j=0;j<3;j++)
if (a+i != x && b+j != y && board[a+i][b+j] == board[x][y])
return false;
return true;
}
bool recursive(vector<vector<char> > &board){
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
{
if(board[i][j]=='.')
{
for(int k=1;k<=9;k++)
{
board[i][j]='0'+k;
if(isValid(board,i,j) && recursive(board))
return true;
board[i][j]='.';
}
return false;
}
}
return true;
}
public:
void solveSudoku(vector<vector<char> > &board) {
recursive(board);
}
};
动态规划,dp[i] 表示源串的前i个字符可以满足分割,那么 dp[ j ] 满足分割的条件是存在k 使得 dp [k] && substr[k,j]在字典里,注意下标[2]:
class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
int n=s.size();
vector<bool> dp(n+1,false);
dp[0]=true;
for(int i=1;i<=n;i++)
{
if(dp[i-1])
{
for(int j=i-1;j<n;j++)
if(dict.count(s.substr(i-1,j-(i-1)+1))>0)
dp[j+1]=true;
}
}
return dp[n];
}
};
(3) Word Break II
跟第一题一样,就是要返回所有可能的切分, 做切分反应是用回溯,但是不剪枝肯定要超时。这里用了一个math[i][j] 来表示 i--j 这一段是否可以切分,然后在dfs的时候利用看最后剩余的子串能否切分来剪枝。[2]
class Solution {
public:
vector<string> wordBreak(string s, unordered_set<string> &dict)
{
int n=s.length();
vector<vector<bool> > match(n+1,vector<bool>(n+1,false));
for(int i=0;i<=n;i++)
match[0][i]=true;
for(int len=1;len<=n;len++)
{
for(int start=0;start+len<=n;start++)
{
string tmp=s.substr(start,len);
if(dict.count(tmp)>0)
match[len][start]=true;
else
{
for(int left=1;left<len;left++)
{
match[len][start]=match[left][start]&&match[len-left][start+left];
if(match[len][start])
break;
}
}
}
}
if(match[n][0]==false)
return vector<string>();
vector<string> ans;
vector<string> had;
dfs(s,0,match,had,ans,dict);
return ans;
}
void dfs(string& s,int k,vector<vector<bool> >& match,vector<string>& had,vector<string>& ans,unordered_set<string> &dict)
{
int n=s.length();
if(k>=n)
{
if(!had.empty())
{
string ret;
for(int i=0;i<had.size();i++)
{
ret.append(had[i]);
if(i!=had.size()-1)
ret.push_back(' ');
}
ans.push_back(ret);
return;
}
}
for(int len=1;k+len<=n;len++)
{
string tmp=s.substr(k,len);
if(dict.count(tmp)>0 && match[n-k-len][k+len])
{
had.push_back(tmp);
dfs(s,k+len,match,had,ans,dict);
had.pop_back();
}
}
}
};
还有一种很快(快10倍!差别在构建dp表的算法)的方法[3]。
[1] http://blog.csdn.net/zxzxy1988/article/details/8586289
[2] http://blog.csdn.net/a83610312/article/details/12870501
[3] http://www.2cto.com/kf/201403/282966.html