【Leetcode】437. Path Sum III解题报告

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dpengwang/article/details/87998680

在这里插入图片描述
求二叉树中的一条路径,使其路径和为定值,该路径必须是从上往下的
基本的思路就是遍历二叉树中的每个点,然后再求以该点为出发点的所有路径
如方法1,方法2

方法1 双递归

外层递归遍历所有点,内层递归遍历以该点为起点的所有路径

class Solution1:
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: int
        """
        if root == None:
            return 0
        else:
            res = 0
            if root.right:
                res += self.pathSum(root.right, sum)
            res += self.getres(root, sum)
            if root.left:
                res += self.pathSum(root.left, sum)

            return res
    def getres(self, root, sumer):
        if root == None:
            return 0
        else:
            res = 0
            if root.val == sumer:
                res +=1
            if root.left:
                res += self.getres(root.left, sumer-root.val)
            if root.right:
                res +=self.getres(root.right, sumer-root.val)
            return res

方法2 递归法的非递归形式

用一个栈非递归遍历二叉树的所有点,另一个栈非递归遍历所有路径
因为外层递归只要遍历到所有点即可,所以不用考虑入栈的顺序

class Solution2:
    #非递归无序遍历二叉树,然后对每个节点进行路径查找
    def pathSum(self, root, sum):
        res = 0
        if root == None:
            return 0
        stack = [root]
        while(len(stack)):
            node = stack.pop()
            res += self.getres(node, sum)
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
        return res

    def getres(self, root, sum):
        stack = [[root,sum]]
        res = 0
        while(len(stack)):
            node,sumer = stack.pop()
            if node.val == sumer:
                res +=1
            if node.left:
                stack.append([node.left, sumer-node.val])
            if node.right:
                stack.append([node.right, sumer-node.val])
        return res

class Solution3:
    #先序遍历,再对每个节点进行递归查路径
    def pathSum(self, root, sum):
        res = 0
        if root == None:
            return 0
        stack = [root]
        while(len(stack)):
            node = stack.pop()
            res += self.getres(node, sum)
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
        return res

    def getres(self, root, sum):
        stack = [[root,sum]]
        res = 0
        while(len(stack)):
            node,sumer = stack.pop()
            if node.val == sumer:
                res +=1
            if node.left:
                stack.append([node.left, sumer-node.val])
            if node.right:
                stack.append([node.right, sumer-node.val])
        return res

方法3 后续遍历加dict

上面两种方法中,对于二叉树的节点都有大量重复的访问和计算,时间复杂度为 O ( n 2 ) O(n^{2}) ,我们可以利用二叉树的后续遍历和一个字典来实现o(n)时间复杂度
核心思想

  • 后续遍历二叉树。对于每个节点,第一次遍历到他时,记录根节点到其路径,加入字典,第二次遍历到他时,即访问他时,判断该点对应的路径和减去sum在字典中出现的次数及路径的条数
  • 要注意的是,每次从一个节点的左子树转到右子树时,要将左子树节点对应的路径和从字典中删除
  • 字典的初始值设为{0:1}
  • 对于sum为0的情况,要将字典中的value减去1(减去自己)
class Solution4:
    def pathSum(self, root, sum):
        if root == None:
            return 0
        from collections import  defaultdict
        dictionary = defaultdict(int)
        dictionary[0] =1
        pNode, curr_sum, stack,res, prev = root, 0, [], 0, None
        while(len(stack) or pNode):
            print(dictionary)
            if pNode:
                curr_sum += pNode.val
                stack.append([pNode, curr_sum])
                dictionary[curr_sum] +=1
                pNode = pNode.left
            else:
                pNode,curr_sum = stack[-1]
                if pNode.right == None or pNode.right == prev:
                    res += dictionary[curr_sum - sum]
                    if sum ==0:
                        res -=1
                    dictionary[curr_sum] -=1
                    stack.pop()
                    prev = pNode
                    pNode = None
                else:
                    pNode = pNode.right
        return res

猜你喜欢

转载自blog.csdn.net/dpengwang/article/details/87998680