Leetcode 113:路径总和 II(最详细的解法!!!)

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

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

示例:
给定如下二叉树,以及目标和 sum = 22

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1

返回:

[
   [5,4,11,2],
   [5,8,4,5]
]

解题思路

这个问题和下面这两个问题很类似。

Leetcode 112:路径总和(最详细的解法!!!)

Leetcode 257:二叉树的所有路径(最详细的解法!!!)

当访问的节点是叶子节点的时候,我们新建一个list,插入到result中,然后返回result。分别遍历左右子树的节点,然后将他们分别插入到叶子节点之前就可以了。

class Solution:
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: List[List[int]]
        """
        result = list()
        if root == None:
            return result

        if not root.left and not root.right and sum == root.val:
            result.append([root.val])
            return result

        left = self.pathSum(root.left, sum - root.val)
        for i in left:
            i.insert(0, root.val)
            result.append(i)

        right = self.pathSum(root.right, sum - root.val)
        for i in right:
            i.insert(0, root.val)
            result.append(i)

        return result

我们看看怎么使用迭代来解决这个问题,这里我们和之前问题Leetcode 257:二叉树的所有路径(最详细的解法!!!)

的写法没有太大的差别,无非是string变成了list,多了个变量sum的区别。

class Solution:
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: List[List[int]]
        """    
        result = list()
        if not root:
            return result

        stack = [(list(), sum, root)]
        while stack:
            path, val_, node = stack.pop()

            if node:
                path.append(node.val)
                if not node.left and not node.right and val_ == node.val:
                    result.append(path)

                stack += [(path.copy(), val_ - node.val, node.left), (path.copy(), val_ - node.val, node.right)]

        return result

这里我们要注意path.copy(),这是因为string是一个不可变类型,它是通过值传递,而list是一个可变类型,它是通过引用传递,如果想要list通过值传递的话,就必须使用copy

这个问题的第一种递归实现cpp版本,有一些陷阱,可以参考我的实现。

class Solution 
{
public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) 
    {
        vector<vector<int>> result;
        if (root == nullptr) return result;
        if (root->left == nullptr and root->right == nullptr and sum == root->val) 
        {
            result.push_back(vector<int>(1, root->val));// 1
            return result;
        }
        vector<vector<int>> left = pathSum(root->left, sum - root->val);
        for (auto& i : left)
        {
            i.insert(i.begin(), 1, root->val);// 2
            result.push_back(i);
        }
        vector<vector<int>> right = pathSum(root->right, sum - root->val);
        for (auto& i : right)
        {
            i.insert(i.begin(), 1, root->val);
            result.push_back(i);
        }
        return result;
    }
};

所以递归的话,我这里更推荐你使用下面回溯的方式去写。

class Solution:
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: List[List[int]]
        """   
        result = list()     
        if not root:
            return result
        
        self._pathSum(result, list(), root, sum)       
        return result
    
    def _pathSum(self,result, path, node, num):
        if node:
            path.append(node.val)
            
            if not node.left and not node.right and num == node.val:
                result.append(path.copy())
            
            self._pathSum(result, path, node.left, num - node.val)
            self._pathSum(result, path, node.right, num - node.val)
            path.pop()

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

你可能感兴趣的:(Problems,leetcode解题指南)