109. 有序链表转换二叉搜索树

给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
      0
     / \
   -3   9
   /   /
 -10  5
def findmid(l,r):
    fast=l
    last=l
    while fast!=r and fast.next!=r:           #链表找中点用快慢指针,这里注意快指针的本身和下一个位置是不是与最后一样判断
        last=last.next
        fast=fast.next.next
    return last
def m(l,r):
    if l==r:return                                #这边注意判断条件就和之前数组里面要是l>r就ruturn
    node=findmid(l,r)
    root=ListNode(node.val)
    root.left=m(l,node)
    root.right=m(node.next,r)
    return root
return m(head,None)                 # 要return

或者转换成数组来做
if not head: return None
lis=[]
while head:
    lis.append(head.val)
    head=head.next
N=len(lis)                #此时链表变成lis数组
left,right =0,N-1
def m(l,r):
    if l>r:
        return None
    mid = (l+r+1)//2
    root = ListNode(lis[mid])
    root.left =m(l,mid-1)
    root.right =m(mid+1,r)
    return root
return m(left,right)

98. 验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
    2
   / \
  1   3
输出: true
res=[]
def m(root):                       # 中序遍历 左根右
    if not root:
        return
    m(root.left)
    res.append(root.val)
    m(root.right)
m(root)
r=res[:]
return sorted(r)==res and len(res)==len(set(res))            #按顺序 且没有重复的

法2:
        mi=float('-inf')
        ma=float('inf')
        def m(root,mi,ma):
            if not root:
                return True
            if root.val<=mi:                  #注意这边含有等号,等号时也是False
                return False
            if root.val>=ma:
                return False
            return m(root.left,mi,root.val) and m(root.right,root.val,ma)
        return m(root,mi,ma)

二叉树的前中后序遍历

前:根左右                                                               
if not root:return []
res=[]
stack=[root]
while stack:
    r=stack.pop()
    res.append(r.val)
    if r.right:                                           
        stack.append(r.right)
    if r.left:                                           #左节点后加进去 为了先pop出来
        stack.append(r.left)
return res

后:左右根                                 可以非递归时用根右左 最后结果倒过来         和前序遍历类似
stack=[root]
res=[]
if not root:
    return res
while stack:
    r=stack.pop()
    res.append(r.val)
    if r.left:
        stack.append(r.left)
    if r.right:
        stack.append(r.right)
return res[::-1]

中:左根右                                       这里因为根在中间 所以和前序和后序处理不同
res=[]
stack=[]
while stack or root:
    while root:
        stack.append(root)
        root=root.left
    r=stack.pop()
    res.append(r.val)
    root=r.right
return res
递归 : 后序
if not root:
	return []
res=[]
def m(root):
    if not root:
        return
                         #前序   res.append(root.val) 
    m(root.left)
                         #中序   res.append(root.val) 
    m(root.right)                                       
    res.append(root.val) #后序   res.append(root.val) 
m(root)
return res

236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
def m(root):
   if not root or root==p or root==q:               # 递归
       return root
   l,r=m(root.left),m(root.right)
   if not l:return r
   if not r:return l 
   if l and r:return root                      #同时不为空 则pq在左右子树一边一个直接返回root
return m(root)

寻找路径的代码

def back(node, path, target, res):
   if not node:
        return
    if node == target:
        path.append(node)
        res.extend(path[:])  # 注意用[:],即浅拷贝
        return
    path.append(node)
    back(node.left, path, target, res)  # 回溯
    back(node.right, path, target, res)
    path.pop()  # 记得恢复状态

res_p = []  # 两个变量,分别存储从根到目标点的路径
res_q = []
back(root, [], p, res_p)
back(root, [], q, res_q)
# 让 res_p 存储路径较小的那个,方便下面遍历查找操作

103. 二叉树的锯齿形层次遍历

给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树 [3,9,20,null,null,15,7],
    3
   / \
  9  20
    /  \
   15   7
返回锯齿形层次遍历如下:
[
  [3],
  [20,9],
  [15,7]
]
res=[]
if not root:return res
temp=collections.deque([root])
j=0                                         # 多设置一个j用来翻转
while temp:
    j+=1                              #
    N=len(temp)
    r=[]
    for i in range(N):
        p=temp.popleft()
        r.append(p.val)
        if p.left:
            temp.append(p.left)
        if p.right:
            temp.append(p.right)
    if j%2:                                  #多了这一步
        res.append(r)
    else:
        res.append(r[::-1])
return res

530. 二叉搜索树的最小绝对差

给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。
示例:
输入:
   1
    \
     3
    /
   2
输出:
1
res=[float('inf'),float('-inf')]         # 直接中序遍历 , res[1]代表pre的值前一个节点的值   res[0]代表差值
def m(root):
    if not root:
        return
    m(root.left)
    res[0]=min(res[0],root.val-res[1])
    res[1]=root.val
    m(root.right)
m(root)
return res[0]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值