剑指offer-Python3版(八)

剑指offer-Python3版(八)

从上到下打印二叉树

Q: 从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

 	    1
       /  \
      2    3
     / \
    4   5 
    输出12345
    这个就是广度优先算法,bfs

思路

一般就是借助队列先进先出

把root节点加入双端队列,

先出队首个节点,加入到result,再看左右子树,有值就先加入tmp队头,(双端对列用append方法是把值放在对列头,这样下一个出队的就是左子树了,嗯,很合理)

class Deque(object):
	def addFront(self, item):
        self.items.append(item)

再出队加入到result,没值就跳出,

跳出之后再出队tmp的首节点…循环到tmp空,结束

class Solution:
    def levelOrder(self, root) -> [int]:
        if not root:
            return []
            # 双端队列 底层是链表,O(1),效率比单纯列表O(N)高
        tmp = collections.deque()
        # result 存放结果 最后return出来
        result = []
        tmp.append(root)
        while tmp:
            # popleft是collections内的方法
            node = tmp.popleft()
            result.append(node.val)
            if node.left:
                tmp.append(node.left)
            if node.right:
                tmp.append(node.right)
        return result

二叉搜索树的后序遍历序列

Q:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

思路

二叉搜索树的特点:对于树中的每个节点X,它的左子树中所有关键字值小于X的关键字值,而它的右子树中所有关键字值大于X的关键字值

递归分治

class Solution:
    def verifyPostorder(self, postorder: [int]) -> bool:
        if not postorder:
            return True

        def isTree(postorder):
            # 根结点
            root = postorder[-1]
            length = len(postorder)
            # 找到左子树
            for i in range(length):
                if postorder[i] > root:
                    break
            # 在右子树中有比root小的,不符合
            for j in range(i, length - 1):
                if postorder[j] < root:
                    return False
            left = True
            if i > 0:
                # 判断左子树是否符合
                left = isTree(postorder[:i])
            right = True
            if i < length - 1:
                # 判断右子树是否符合
                right = isTree(postorder[i:-1])
            # return right if left else left
            # 如果left成立返回right
            return left and right

        return isTree(postorder)

二叉树中和为某一值的路径

Q:输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。

示例:
给定如下二叉树,以及目标和 sum = 225
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1
返回:

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

思路

回溯法

recur()

递推工作:
路径更新: 将当前节点值 root.val 加入路径 path ;
目标值更新: tar = tar - root.val(即目标值 tar 从 sum 减至0);
路径记录: 当 ① root 为叶节点 且 ② 路径和等于目标值 ,则将此路径 path 加入 res 。
先序遍历: 递归左 / 右子节点。
路径恢复: 向上回溯前,需要将当前节点从路径 path 中删除,即执行 path.pop() 。

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> [[int]]:
        # 创建2个列表 存放最终结果,以及走过的路径
        res, path = [], []

        def recur(root, tar):
            """

            @param root:当前节点
            @param tar: 当前目标值
            @return: res
            """
            if not root:  # 空就直接返回
                return
            path.append(root.val)
            tar -= root.val  # 目标值更新
            if tar == 0 and not root.left and not root.right:
                # 用list(path),后序的操作不会使这里的path收到影响
                # 相当于新建并复制了一个path列表
                res.append(list(path))
            recur(root.left, tar)
            recur(root.right, tar)
            # 回溯前,清空path
            path.pop()

        recur(root, sum)
        return sum

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值