【剑指 Offer 随笔】(中等)34. 二叉树中和为某一值的路径 --- 深度优先搜索 + 先序遍历

  • 34 二叉树中和为某一值的路径
  • 来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof
  • 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
  • 示例:
给定如下二叉树,以及目标和 sum = 22,

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

解题思路:【c++】深度优先搜索+先序遍历:从根节点开始先序遍历。定义全局变量path,sumList分别存储当前路径及满足条件的路径。递归参数cur节点与当前路径总和与目标值的差值curSum,若cur==NULL,返回空,否则,将cur值val加入path,当前差值curSum=sum-val,判断cur为叶子结点(左右子节点均为NULL)且curSum==0代表已找到满足条件的路径,将path加入到sumList中。递归调用遍历其左子树与右子树,将已遍历的节点从path中删去。

// c++
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> path;
    vector<vector<int>> sumList;
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        dfs(root, sum);
        return sumList;
    }
    void dfs(TreeNode *root, int cur_sum){
        if (root==NULL) return;
        // cout<< root->val<<endl;
        path.push_back(root->val);
        cur_sum = cur_sum - root->val;
        // cout<<"cur:"<< cur_sum<<endl;
        // cout<<"size:"<<path.size()<<endl;
        if (cur_sum == 0 && (root->left == NULL) && (root->right ==NULL))
        {
            sumList.push_back(path);
        }
        dfs(root->left, cur_sum);
        dfs(root->right, cur_sum);
        path.pop_back(); //删去最末节点
    }
};
# python 3
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        path = [] #记录当前路径
        sumList = [] #记录满足条件的路径
        def dfs(root, curSum):
            if not root: return 
            #print (root.val) #先序遍历
            path.append(root.val)
            curSum = curSum - root.val
            #记录路径不能直接执行 res.append(path) ,(因为将 path 对象加入了 res ,后续 path 改变时, res 中的 path 对象也会随之改变。),应该执行 res.append(list(path)) ,相当于复制了一个 path 并加入到 res
            if curSum==0 and not root.left and not root.right:
                sumList.append(list(path))
                
            dfs(root.left, curSum)
            dfs(root.right, curSum)
            path.pop() #需要删除路径

        dfs(root, sum)
        return sumList

Notes: python3中记录路径不能直接执行 res.append(path) ,(因为将 path 对象加入了 res ,后续 path 改变时, res 中的 path 对象也会随之改变。)应该执行 res.append(list(path)) ,相当于复制了一个 path 并加入到 res。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
1. 创建二叉树二叉树是一种树形结构,其每个节点最多有两个子节点,我们可以通过递归的方式来创建一个二叉树。具体步骤如下: 首先,我们需要定义二叉树节点的结构体: ``` struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; ``` 然后,我们可以通过递归方式创建二叉树,示例代码如下: ``` TreeNode* createTree() { int val; cin >> val; // 输入节点的值 if (val == -1) { // 如果值为-1,表示该节点为空 return NULL; } TreeNode* root = new TreeNode(val); root->left = createTree(); // 递归创建左子树 root->right = createTree(); // 递归创建右子树 return root; } ``` 2. 先序遍历二叉树先序遍历先访问节点本身,再遍历其左子树和右子树。示例代码如下: ``` void preorderTraversal(TreeNode* root) { if (root == NULL) { return; } cout << root->val << " "; // 访问节点本身 preorderTraversal(root->left); // 遍历左子树 preorderTraversal(root->right); // 遍历右子树 } ``` 3. 序遍历二叉树1: 序遍历是先遍历左子树,再访问节点本身,最后遍历右子树。示例代码如下: ``` void inorderTraversal1(TreeNode* root) { if (root == NULL) { return; } inorderTraversal1(root->left); // 遍历左子树 cout << root->val << " "; // 访问节点本身 inorderTraversal1(root->right); // 遍历右子树 } ``` 4. 序遍历二叉树2: 与序遍历1不同,这里给出一种非递归的序遍历方法,需要使用到栈。示例代码如下: ``` void inorderTraversal2(TreeNode* root) { stack<TreeNode*> st; TreeNode* p = root; while (p != NULL || !st.empty()) { while (p != NULL) { st.push(p); p = p->left; } p = st.top(); st.pop(); cout << p->val << " "; p = p->right; } } ``` 5. 后序遍历二叉树: 后序遍历是先遍历左子树,再遍历右子树,最后访问节点本身。示例代码如下: ``` void postorderTraversal(TreeNode* root) { if (root == NULL) { return; } postorderTraversal(root->left); // 遍历左子树 postorderTraversal(root->right); // 遍历右子树 cout << root->val << " "; // 访问节点本身 } ``` 6. 层序遍历二叉树: 层序遍历是按照从上到下、从左到右的顺序遍历每个节点。需要使用到队列。示例代码如下: ``` void levelOrderTraversal(TreeNode* root) { if (root == NULL) { return; } queue<TreeNode*> q; q.push(root); while (!q.empty()) { TreeNode* node = q.front(); q.pop(); cout << node->val << " "; if (node->left != NULL) { q.push(node->left); } if (node->right != NULL) { q.push(node->right); } } } ``` 7. 求二叉树的深度: 二叉树的深度是从根节点到最远叶子节点的最长路径上的节点数。可以使用递归方式求解。示例代码如下: ``` int maxDepth(TreeNode* root) { if (root == NULL) { return 0; } int leftDepth = maxDepth(root->left); int rightDepth = maxDepth(root->right); return max(leftDepth, rightDepth) + 1; } ``` 8. 退出
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值