leetcode——二叉树问题

题目一描述(重建二叉树)

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

题目分析

先序遍历特点:第一个值是根节点(中左右)
中序遍历特点:根节点左边都是左子树,右边都是右子树(左中右)

思路:

首先根据根节点a将中序遍历划分为两部分,左边为左子树,右边为右子树
在左子树中根据第一条规则递归,得出左子树
在右子树中根据第一条规则递归,得出右子树
最后合成一棵树(转自牛客评论)

代码

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
    	# pre具有列表性质
        # write code here
        if not pre or not tin :
            return None
        res = TreeNode(pre.pop(0))
        index = tin.index(res.val)
        res.left = self.reConstructBinaryTree(pre, tin[:index])
        # 这里是一个妙处,因为之前是pop函数,pre经过左子树的函数过后,仅仅只剩右子树函数
        res.right = self.reConstructBinaryTree(pre, tin[index+1:])
        return res

class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if not pre or not tin:
        	return None
        else:
            ans = TreeNode(pre[0])
            ans.left = self.reConstructBinaryTree(pre[1:tin.index(pre[0])+1], tin[:tin.index(pre[0])])
            ans.right = self.reConstructBinaryTree(pre[tin.index(pre[0])+1:], tin[tin.index(pre[0])+1:])
            return ans

题目二描述(第k小元素)

给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。

 输入: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
输出: 1

输入: root = [5,3,6,2,4,null,null,1], k = 3
       5
      / \
     3   6
    / \
   2   4
  /
 1
输出: 3

题目分析

给的二叉树是按照中序顺序进行的,即将二叉树进行中序遍历,然后选取第k个值即可

中序遍历代码

  # 递归版本
class Solution(object):
    def inorderTraversal(self, root):
        def core(root,res):
            if root:
                core(root.left,res)
                res.append(root.val)
                core(root.right,res)

        res=[]
        core(root,res)
        return res


###  循环写法
class Solution(object):
    def inorderTraversal(self, root):
        stack=[]
        res=[]
        node=root
        while node or len(stack)>0:
            if node:
                stack.append(node)
                node=node.left
            else:
                node=stack.pop()
                res.append(node.val)
                node=node.right
        return res

题目代码

递归版本

### 中序递归版
class Solution(object):
    def kthSmallest(self, root, k):
        self.count=k
        self.res=0
        def core(root):
            if  root :
                core(root.left)
                self.count=self.count-1
                if self.count==0:
                    self.res=root.val 
                core(root.right)

        core(root)
        return self.res

循环版本

####   中序循环版本
class Solution(object):
    def inorderTraversal(self, root):
        stack=[]
        res=[]
        node=root
        while node or len(stack)>0:
            if node:
                stack.append(node)
                node=node.left
            else:
                node=stack.pop()
                res.append(node.val)
                node=node.right
        return res

题目三–公共祖先

题目描述

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

题目分析

根据BST(二叉搜索树)的特点,节点共三种情况:

p,q都在左子树(二者的值都小于根的值)
p,q都在右子树 (二者的值都大于根的值)
p,q分别在左右子树(此时最近公共祖先为root

代码

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if max(p.val,q.val) < root.val:
            return self.lowestCommonAncestor(root.left,p,q)
        if min(p.val,q.val) > root.val:
            return self.lowestCommonAncestor(root.right,p,q)
        return root

当二叉树不是搜索二叉树时:

题目分析

后序遍历(自底向上)。一旦遇到p、q、满足条件的节点,就向上传递,最后传递到顶端的就是满足条件的节点

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

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if root == None or root == p or root == q:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        ##  由下而上考虑  如果符合条件就把符合条件的节点向上传递
        if left and right:
            return root
         ##  由下而上考虑  如果满足左右两边都有p,q
        return left if left else right
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值