Likou Problem Solution 34: A path whose sum is a certain value in a binary tree. Method: backtracking method (loop + recursion), modification on DFS (path record)

1. Title description: Link
Enter a binary tree and an integer, and print out all paths where the sum of node values ​​in the binary tree is the input integer. Starting from the root node of the tree and going down to the nodes passed by the leaf nodes form a path.
Example: Given the following binary tree, and the goal and sum = 22,

          5
         / \
        4   8
       /   / \
      11  13  4
     /  \    / \
    7    2  5   1
返回:
[
[5,4,11,2],
[5,8,4,5]
]

2. Ideas:
Binary tree path search problem/matrix path search problem, First think of DFS, but need to return when the path is incorrect, so think of the backtracking method.

2.1. The key to the retrospective method:

  • Record the current path before the recursive function starts, and remove the current path after the recursive function ends.
  • The basic mode of the backtracking method is for loop + recursive function, and the for loop may unfold and become a traversal of each situation.
    The for loop handles various possible situations of the parameters in the current recursive function;
    the recursive function in the for loop performs the next stage of recursion in the current situation.

2.2, backtracking pseudo-code:
thinking links, author: luo-jing-yu-yu

result = []
void backtrack(路径,选择列表){
    
    
    if 满足结束条件{
    
    
       result.add(路径)
       return ; 
	}
    for 选择 in 选择列表{
    
    
       做选择
       backtrack(路径,选择列表)
       撤销选择
	}
}

The core is the recursion in the for loop, which "makes a selection" before the recursive call, and "cancel the selection" after the recursive call.
The selection part generally needs to record the elements that have been visited to avoid repeated visits, such as adding a used[] array or visited[] array.
Example: Interview Question 38. Arrangement of Strings

3. C++ code:

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();  // 移除当前路径,回溯的关键
    }
};

Similar topics: 93. Recover IP address

to sum up

1. When the backtracking method needs to record the path, add the pop() function at the end of the dfs function.
2. The basic mode of the backtracking method is for loop + recursive function. The for loop may unfold and become a traversal of each situation.

Guess you like

Origin blog.csdn.net/qq_33726635/article/details/106456655