深度优先算法--对DFS的一些小小的总结(一)
提到DFS,我们首先想到的是对树的DFS,例如下面的例子:
求二叉树的深度
int TreeDepth(BinaryTreeNode* root){
if(root==nullptr)return 0;
int left=TreeDepth(root->left);
int right=TreeDepth(root->right);
return (left>right)?(left+1):(right+1);
}
求二叉树的最小路径深度
int TreeDepth(BinaryTreeNode* root){
if(root=nullptr)return 0;
int left=TreeDepth(root->left);
int right=TreeDepth(root->right);
if(left==0||right==0)return 1+left+right;
return 1+min(left,right);}
或许考察的更深入一些
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
vector<vector<int> >path;//用来记录路径
vector<int> pathnum;
vector<vector<int> >FindPath(TreeNode* root,int expectNumber){
if(root==nullptr)return path;
int curSum=0;
curSum+=root->val;
pathnum.push_back(root->val);
bool isleaf=!(root->left)&&!(root->right);
if(curSum==expectNumber&&isleaf)path.push_back(pathnum);
if(root->left)FindPath(root->left,expectNumber-root->val);
if(root->right)FindPaht(root->right,expectNumber-root->val);
curSum-=root->val;
pathnum.pop_back();
return path;
}
有上面可以看出,DFS面对树的搜索,采用递归,有很好的效果,通常的步骤是
搜索到叶节点,采取的措施
#如果当前状态满足最终的解,则添加到最终解中
# 遍历构造空间,是当前构造解可添加处理操作的空间
# 如果当前遍历的操作对于当前阶段是可行的,则对当前构造解施加操作
#若满足从当前状态下进入下一步处理,进一步搜索解
#从下一个状态搜索状态中返回,无论下一层的是否什么状态。回复本阶段的状态,搜索笨阶段另外可施加的状态
进行操作
上面讲了这么多,然而最近经常发现DFS被应用于字符串或数组的搜索,那么在什么样的情况下需要使用到DFS以及我们使用DFS会达到什么样的效果呢?
下面是一个字符串中是否有回文字段的题,典型的符合上面的状态解释
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s ="aab",
Return
{ ["aa","b"], ["a","a","b"] }
void dfs(string s,vector<string> &path,vector<vector<string> >&res)
{
if(s.empty()){
res.push_back(path);
return;
}
for(int i=0;i<s.size();i++){
string s.substr(0,i+1);
if(Is_palindrome(a))//Is_palindrome判断是否是回文字段函数,这里省略不写了
path.push_back(s.substr(0,i+1));
dfs(s,substr(i+1),path,res);
path.pop_back();
}
}
vector<vector<string> >patition(string s){
vector<vector<string> >res;
vector<string> path;
dfs(s,path,res);
return res;
}