1.タイトルの説明:リンク
バイナリツリーと整数を入力し、バイナリツリーのノード値の合計が入力整数であるすべてのパスを出力します。ツリーのルートノードから始まり、リーフノードによって渡されたノードに至ると、パスが形成されます。
例:次のバイナリツリーと、目標と合計= 22が与えられた場合、
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[
[5,4,11,2],
[5,8,4,5]
]
2.アイデア:
二分木経路探索問題/行列経路探索問題、まずDFSについて考えますが、パスが正しくない場合に戻る必要があるため、バックトラック方式について考えます。
2.1。回顧的方法の鍵:
- 再帰関数が開始する前に現在のパスを記録し、再帰関数が終了した後に現在のパスを削除します。
- バックトラッキング方式の基本モードはforループ+再帰関数であり、forループが展開して各状況のトラバーサルになる場合があります。
forループは、現在の再帰関数のパラメーターで考えられるさまざまな状況を処理します。forループ
の再帰関数は、現在の状況で再帰の次の段階を実行します。
2.2、バックトラッキング疑似コード:
思考リンク、作者:luo-jing-yu-yu
result = []
void backtrack(路径,选择列表){
if 满足结束条件{
result.add(路径)
return ;
}
for 选择 in 选择列表{
做选择
backtrack(路径,选择列表)
撤销选择
}
}
コアはforループの再帰です。これは、再帰呼び出しの前に「選択を行い」、再帰呼び出しの後に「選択をキャンセル」します。
選択部分は、used []配列やvisited []配列の追加など、繰り返しアクセスされるのを防ぐために、アクセスされた要素を記録する必要があります。
例:インタビューの質問38.文字列の配置
3. C ++コード:
class Solution {
private:
vector<vector<int>> ans;
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
// 主函数入口
vector<int> tmp;
if(root == NULL) return ans;
findPath(tmp,root,sum);
return ans;
}
void findPath(vector<int>& tmp,TreeNode* root, int currVal){
//DFS
if(root == NULL) return ;
if(root->val == currVal && root->left == NULL && root->right == NULL){
// 终止条件
tmp.push_back(root->val);
ans.push_back(tmp);
tmp.pop_back();
return;
}
//递归核心部分代码:
tmp.push_back(root->val); // 记录当前路径
// 以下两行相当于for循环的展开,(实际为前序遍历)
findPath(tmp,root->left,currVal-root->val); //递归,当前递归函数结束返回时实现回溯
findPath(tmp,root->right,currVal-root->val);
// 遍历完了左右子树,需要将当前节点从子序列中移除掉,可以联想到回溯算法
tmp.pop_back(); // 移除当前路径,回溯的关键
}
};
同様のトピック:93. IPアドレスの回復
総括する
1.バックトラッキングメソッドがパスを記録する必要がある場合は、dfs関数の最後にpop()関数を追加します。
2.バックトラッキング方式の基本モードはforループ+再帰関数であり、forループが展開して各状況のトラバーサルになる場合があります。