Likou Problem Solution 34:合計がバイナリツリーの特定の値であるパス。方法:バックトラッキング方法(ループ+再帰)、DFSでの変更(パスレコード)

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ループが展開して各状況のトラバーサルになる場合があります。

おすすめ

転載: blog.csdn.net/qq_33726635/article/details/106456655