剑指 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