代码随想录算法训练营第十八天

513. 找树左下角的值

题目链接:找树左下角的值
看了一眼提示迭代简单,递归有难度,果然递归写了一个小时发现提看错了,不是最底层的左叶子,右叶子也可以的!!!只要是最后一层最左边的就行,写完了发现右叶子也行。

迭代

class Solution(object):
    def findBottomLeftValue(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        queue = collections.deque()
        res = []
        queue.append(root)
        size = 1
        while queue:
            l = []
            for _ in range(size):
                cur = queue.popleft()
                l.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            res.append(l)
            size = len(queue)
        return res[-1][0]

这个题迭代确实很容易,就是层序遍历最后一层的第一个元素就行。
顺便这里提醒一下自己,在append进l的时候,最好在popleft的时候append,别在append进queue的时候append,不然会多一个空list的。

递归

# 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 findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        max_depth = -inf
        max_node = root.val
        def traversal(root,depth):
            nonlocal max_depth, max_node
            if (not root.left) and (not root.right):
                if max_depth < depth:
                    max_depth=depth
                    max_node = root.val
            if root.left:
                traversal(root.left,depth+1)
            if root.right:
                traversal(root.right,depth+1)
            
        traversal(root,0)
        return max_node

还是回溯,为什么不用

depth+=1
traversal(root.left,depth+1)
depth-=1

113里会写

nonlocal和global

  1. global是全局变量,变量定义在函数外部的时候,如果函数里面想改变这个全局变量的值,需要在当前的引用函数里面重新定义一个变量 并用关键字global修饰。
a=1
def b():
	global a
	a+=1
	print(a)
b()
  1. nonlocal非全局变量,在函数的函数里面使用函数的变量。
def b():
	num2=1
	def c():
		nonlocal num2#为了修改非全局变量
		num2+=2
		print(num2)
	return c
b()

这道题是def套def用unlocal。

路径总和

112. 路径总和

题目链接:路径总和
这题什么都不写的时候自动输出False,PathSum最后的return False不写也没事。
在哪里要return上搞了很久

错误return

查了半天,sum都算出来了,就是不出True,最后理了一遍,问题应该在return上,在if root.left:root.right:这里,就算PathSum(root.left,sum+root.left.val,targetSum)得到了True,没有return就等于啥也没有。
但是直接return PathSum(root.left,sum+root.left.val,targetSum)也是错的,因为这样整个function就直接断掉了。

class Solution(object):
    def hasPathSum(self, root, targetSum):
        """
        :type root: TreeNode
        :type targetSum: int
        :rtype: bool
        """
        def PathSum(root,sum,targetSum):
            if (not root.left) and (not root.right):
                if sum == targetSum:
                    return True
            
            if root.left:
            	PathSum(root.left,sum+root.left.val,targetSum)
            if root.right:
            	PathSum(root.right,sum+root.right.val,targetSum)
            return False

        if not root:
            if targetSum != 0:
                return False
        else:
            return PathSum(root,root.val,targetSum)

递归

正确的办法是得到True了,return一下。

class Solution(object):
    def hasPathSum(self, root, targetSum):
        """
        :type root: TreeNode
        :type targetSum: int
        :rtype: bool
        """
        def PathSum(root,sum,targetSum):
            if (not root.left) and (not root.right):
                #t(sum)
                if sum == targetSum:
                    #print(1)
                    return True
            
            if root.left:
                if PathSum(root.left,sum+root.left.val,targetSum):
                    return True
            if root.right:
                if PathSum(root.right,sum+root.right.val,targetSum):
                    return True
            return False

        if not root:
            if targetSum != 0:
                return False
        else:
            return PathSum(root,root.val,targetSum)

简洁版递归

因为不知道要怎么统计sum所以多写了一个函数,可以直接在targetSum上动。

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False
        
        if not root.left and not root.right:
            if targetSum==root.val:
                return True
            else:
                return False
        else:
            return self.hasPathSum(root.left,targetSum-root.val) or self.hasPathSum(root.right,targetSum-root.val)

迭代

很久以前自己写的迭代,有空再写一次吧。

class Solution(object):
    def hasPathSum(self, root, targetSum):
        """
        :type root: TreeNode
        :type targetSum: int
        :rtype: bool
        """                
        from collections import deque
        if not root:
            return False
        que_root=deque([root])
        que_sum=deque([root.val])
        while que_root:
            node=que_root.popleft()
            s=que_sum.popleft()
            if not node.left and not node.right:
                if targetSum==s:
                    return True
            
            if node.left:
                que_root.append(node.left)
                que_sum.append(s+node.left.val)
            if node.right:
                que_root.append(node.right)
                que_sum.append(s+node.right.val)
                
        return False    

113. 路径总和ii

题目链接:路径总和ii

递归

class Solution(object):
    def pathSum(self, root, targetSum):
        """
        :type root: TreeNode
        :type targetSum: int
        :rtype: List[List[int]]
        """
        def whichpath(root,path,targetSum,res):
            if (not root.left) and (not root.right):
                if sum(path) == targetSum:
                    res.append(path[:])#这里一定要加:
            else:
                if root.left:
                    path.append(root.left.val)
                    whichpath(root.left,path,targetSum,res)
                    path.pop()
                if root.right:
                    path.append(root.right.val)
                    whichpath(root.right,path,targetSum,res)
                    path.pop()
        res = []
        path = []
        if not root:
            return res
        path.append(root.val)
        whichpath(root,path,targetSum,res)
        return res

关于path[:]:中间不可以写path,因为path是引用,而path[:]是拷贝数据进去,引用的话,这么递归下去,path自己发生了改变,会影响到res里已经append进去的path,所以最后的得到的答案都是只有[root.val](递归到最后得到的);如果是path[:]就是复制切片,所以后面的递归里path发生了改变也不会影响到复制体。
path是list所以一定要pop,上一题,sum是个值,包括昨天的回溯,path也是个值,在进入递归之后会产生新的值,所以没有关系,但这里是list,每次都是append进去,并不会有一个新的list出现,所以每次都要pop。

从中序与后序遍历序列构造二叉树

106.从中序与后序遍历序列构造二叉树

题目链接:从中序与后序遍历序列构造二叉树
这个题最重要的是所有元素不重复,所以后序的最后一个元素是root,在中序找到这个元素就可以找到左右孩子的长度而不用担心会不会重复。
中序:左中右
后序:左右中

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        if len(inorder) == 0:
            return None
        tree = TreeNode(val=postorder[-1])
        r = inorder.index(postorder[-1])
        if len(inorder) == 1:
            return tree
        tree.left = self.buildTree(inorder[:r], postorder[:r])
        tree.right = self.buildTree(inorder[(r+1):], postorder[r:(len(postorder)-1)])
        return tree

105.从前序与中序遍历序列构造二叉树

题目链接:从前序与中序遍历序列构造二叉树
这个也差不多。

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        if len(inorder) == 0:
            return None
        tree = TreeNode(val=preorder[0])
        r = inorder.index(preorder[0])
        if len(inorder) == 1:
            return tree
        tree.left = self.buildTree(preorder[1:(1+r)],inorder[:r])
        tree.right = self.buildTree(preorder[(1+r):],inorder[(r+1):])
        return tree
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值