树的搜索-二叉树中和为某一值的路径、二叉搜索树与双向链表、右根左遍历

剑指 Offer 34. 二叉树中和为某一值的路径

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

要记录路径的值
找到路径之后不需要return

又遇到python 巨坑:
在这里插入图片描述
在这里插入图片描述

排除这个问题,总算成功

# 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 pathSum(self, root: TreeNode, target: int) -> List[List[int]]:
        res = []
        record = []
        def pre_order(node, key):
            if not node: return
            # 不能提前减枝
            # if key + node.val > target: return # 遇到问题:[-2,null,-3]  target为-5
            # 当前位置还小于target
            key += node.val
            record.append(node.val)
            # 如果是叶子节点
            if not node.left and not node.right and key==target:
                # res.append(record) # 错误,应改为:
                res.append(list(record))
                # print(record) #这里print与答案一样 问题是res没有值
                # print(res) #这里可以发现问题所在:res.append(record) 是把record对象加入
                # return # 不需要return 因为还要减去当前节点的值
            
            pre_order(node.left, key)
            pre_order(node.right, key)
            
            key -= node.val
            record.pop()

        pre_order(root, 0)
        return res

参考答案

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        res, path = [], []
        def recur(root, tar):
            if not root: return
            path.append(root.val)
            tar -= root.val
            if tar == 0 and not root.left and not root.right:
                res.append(list(path))
            recur(root.left, tar)
            recur(root.right, tar)
            path.pop()

        recur(root, sum)
        return res

发现我的代码中:
key -= node.val # 不影响,因为上一层递归的key不同该层的key

剑指 Offer 36. 二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。 我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

二叉排序树通过中序遍历得有序数列
左右子树变成前继后继

先用数组存储遍历好的节点,再修改指针,这样容易一点。(相比于一边遍历一边改指针)
按照左——根——右 的处理
实际上,我们只要找到上一个遍历节点就可以,因为上一个节点已经读取,改变它的子树并不会影响接下来的遍历,pre(已经访问过的)要改变右子树,已经访问说明已进入右子树;cur(当前访问)要改变左子树,左边的肯定已经访问完。
在这里插入图片描述
在这里插入图片描述

"""
# Definition for a Node.
class Node:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
"""
class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        def dfs(cur):
            if not cur: return None
            # dfs(cur.left, pre)
            dfs(cur.left)
            if self.pre == None: # 第一个节点不用处理指针
                self.head = cur
            else: # cur 与 pre 的连接
                self.pre.right = cur
                cur.left = self.pre
            # 更新上一个节点
            self.pre = cur
            dfs(cur.right)
            # return pre # 这样无法追踪最后的pre

        if not root: return None # 因为后面有操作,需要提前退出
        # pre = None
        self.pre = None
        self.head = None
        # pre = dfs(root, pre)
        dfs(root)
        self.head.left, self.pre.right = self.pre, self.head
        return self.head


剑指 Offer 54. 二叉搜索树的第k大节点

给定一棵二叉搜索树,请找出其中第k大的节点。

思想:
中序遍历为递增序列,中序遍历倒序为递减序列
左根右为递增序列,则右根左为递减序列
在这里插入图片描述

记录第k个节点 和 提前终止

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def kthLargest(self, root: TreeNode, k: int) -> int:
        self.k = k # int类型没用地址,不像前面的list可以在函数内使用
        def dfs(root):
            if not root or self.k == 0: return
            # if not root: return
            dfs(root.right)
            # if self.k == 0: return
            if self.k == 1:
                self.res = root.val
                # add
                self.k -= 1
                return # 逻辑不对 这里没有减一就返回了
            self.k -= 1
            dfs(root.left)
        
        # self.key = k
        dfs(root)
        return self.res

官方答案

class Solution:
    def kthLargest(self, root: TreeNode, k: int) -> int:
        def dfs(root):
            if not root: return
            dfs(root.right)
            if self.k == 0: return
            self.k -= 1
            if self.k == 0: self.res = root.val
            dfs(root.left)

        self.k = k
        dfs(root)
        return self.res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值