二叉树的遍历过程:以 Path Sum 为例
为了最终输出所有可能的路径,我们需要在遍历时记录当前路径,当发现路径满足条件时,就将路径保存下来。路径遍历的顺序实际上就是 DFS 的顺序。当 DFS 进入一个结点时,路径中就增加一个结点;当 DFS 从一个结点退出时,路径中就减少一个结点。下面的 GIF 动图展示了这个过程。
回溯算法的递归与遍历策略
回溯(backtracking) 实际上就是“撤回一步”的意思。而在二叉树的 DFS 遍历中,从一个结点退出就是一种回溯。回溯法和 DFS 是息息相关的。例如,使用 DFS 遍历这个二叉树中的路径,在走到结点 7 之后,下一步就是退回一个结点(递归函数返回),再进入结点 2。这样的一个退回步骤就是回溯。
根据回溯操作的特性,我们使用栈记录遍历时的当前路径。当进入一个结点时,做 push 操作;当退出一个结点时,做 pop 操作,进行回溯
回溯算法例题:Subsets
1.给定一个二叉树和一个目标和,找到所有从根结点到叶结点的路径,使得路径上所有结点值相加等于目标和。示例:给定如下二叉树,以及目标和 sum = 22
class solution{
public:
vector<vector<int>> pathSum(TreeNode* root, int sum){
vector<vector<int>> aw;//成功方案
vector<int> temp;//当前方案
backtrack(root,aw,temp,sum,0);
return aw;
}
backtrack(TreeNode* root,vector<vector<int>> &aw,vector<int> &temp,int sum,int cursum){
if(root==NULL) return;
temp.push_back(root->val);
cursum+=root.value;
if(cursum==sum&&isLeaf(root)){
aw.push_back(temp);
temp.pop_back();
return;
}//找到一条路径
backtrack(root->left,aw,temp,sum,0);
backtrack(root->right,aw,temp,sum,0);
temp.popback();
cursum-=root.value;
}
bool isLeaf(TreeNode *t) {
return (t->left==NULL && t->right==NULL);
}
};