二叉树——10.路径总和

力扣题目链接

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

解题思路如下:

为了判断是否存在这样的一条路径,代码需要采用递归回溯的方式进行树的遍历。具体步骤如下:

  1. 递归遍历每个节点:从根节点开始,逐步向下遍历二叉树的每个节点。在遍历过程中,不断更新当前路径的节点值之和,判断是否能够达到目标和。

  2. 递归终止条件:递归的终止条件有两个:

    • 当遍历到一个叶子节点时,如果当前路径的节点值之和等于目标和,则返回True,表示找到了这样的一条路径。但这样代码比较麻烦,可以用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。
    • 如果遍历到叶子节点但未达到目标和,或者当前节点的左右子树都没有满足条件的路径,则返回False
  3. 回溯:如果当前节点的左右子树都没有找到满足条件的路径,那么需要回溯,即撤销对当前节点的处理,并继续探索其他可能的路径。

完整代码如下:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def traversal(self, cur: TreeNode, count: int) -> bool:
        if not cur.left and not cur.right and count == 0: # 遇到叶子节点,并且计数为0
            return True
        if not cur.left and not cur.right: # 遇到叶子节点直接返回
            return False
        
        if cur.left: # 左
            count -= cur.left.val
            if self.traversal(cur.left, count): # 递归,处理节点
                return True
            count += cur.left.val # 回溯,撤销处理结果
            
        if cur.right: # 右
            count -= cur.right.val
            if self.traversal(cur.right, count): # 递归,处理节点
                return True
            count += cur.right.val # 回溯,撤销处理结果
            
        return False
    
    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if root is None:
            return False
        return self.traversal(root, sum - root.val)  

首先,检查当前节点是否是叶子节点(即没有左子节点和右子节点),并且剩余目标和为零。如果条件满足,则返回 True,表示找到了满足条件的路径。如果当前节点是叶子节点,但剩余目标和不为零,则返回 False,表示这条路径不满足条件。

        if cur.left:
            count -= cur.left.val
            if self.traversal(cur.left, count):
                return True
            count += cur.left.val

如果当前节点有左子节点,则执行以下步骤:

  1. 从count中减去左子节点的值。
  2. 递归调用traversal方法,传入左子节点和新的count值。
  3. 如果递归调用返回 True,则直接返回 True,表示找到了满足条件的路径。
  4. 如果递归调用返回 False,则将count的值加回来,进行回溯,撤销之前的计算。

右子节点同理。如果当前节点的左右子节点都不存在满足条件的路径,则返回 False

    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if root is None:
            return False
        return self.traversal(root, sum - root.val)  

检查根节点是否为空。如果为空,则返回 False,表示不存在任何路径。调用 traversal 方法,传入根节点和 sum - root.val 作为参数。sum - root.val 表示从目标和中减去根节点的值,剩下的值将作为新的目标和传递给 traversal 方法。

  • 19
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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. 退出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值