【LeetCode】108.将有序数组转换为平衡二叉树(中序遍历三种方法,java实现)

题目

链接

image-20200625004437435

解析

遍历树的方法。DFS(先序遍历,中序遍历,后序遍历);BFS。

遍历树的两种通用策略:

  • 深度优先遍历DFS

    这种方法以深度 depth 优先为策略,从根节点开始一直遍历到某个叶子节点,然后回到根节点,在遍历另外一个分支。
    根据根节点,左孩子节点和右孩子节点的访问顺序又可以将 DFS 细分为先序遍历 preorder,中序遍历 inorder 和后序遍历 postorder

  • 广度优先遍历BFS

    按照高度顺序,从上往下逐层遍历节点。
    先遍历上层节点再遍历下层节点。

下图中按照不同的方法遍历对应子树,得到的遍历顺序都是 1-2-3-4-5。根据不同子树结构比较不同遍历方法的特点。

![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWMubGVldGNvZGUtY24uY29tL0ZpZ3VyZXMvMTA4L2Jmc19kZnMucG5n?x-oss-process=image/format,png width=500 height=250)

将有序数组转换为二叉搜索树的结果为什么 不唯一

众所周知,二叉搜索树的中序遍历是一个升序序列。

将有序数组作为输入,可以把该问题看做 根据中序遍历序列创建二叉搜索树

这个问题的答案唯一吗。例如:是否可以根据中序遍历序列和二叉搜索树之间是否一一对应,答案是 否定的

下面是一些关于 BST 的知识。

  • 中序遍历不能唯一确定一棵二叉搜索树。
  • 先序和后序遍历不能唯一确定一棵二叉搜索树。
  • 先序/后序遍历和中序遍历的关系:
    inorder = sorted(postorder) = sorted(preorder)
  • 中序+后序、中序+先序可以唯一确定一棵二叉树。

因此,“有序数组 -> BST”有多种答案。

img

因此,添加一个附件条件:树的高度应该是平衡的、例如:每个节点的两棵子树高度差不超过 1。

这种情况下答案唯一吗?仍然没有。

img

高度平衡意味着每次必须选择中间数字作为根节点。这对于奇数个数的数组是有用的,但对偶数个数的数组没有预定义的选择方案。

img

对于偶数个数的数组,要么选择中间位置左边的元素作为根节点,要么选择中间位置右边的元素作为根节点,不同的选择方案会创建不同的平衡二叉搜索树。方法一始终选择中间位置左边的元素作为根节点,方法二始终选择中间位置右边的元素作为根节点。方法一和二会生成不同的二叉搜索树,这两种答案都是正确的。

方法一:中序遍历:始终选择中间位置左边元素作为根节点

算法

img

  • 方法 helper(left, right) 使用数组 nums 中索引从 leftright 的元素创建 BST:
    • 如果 left > right,子树中不存在元素,返回空。
    • 找出中间元素:p = (left + right) // 2
    • 创建根节点:root = TreeNode(nums[p])
    • 递归创建左子树 root.left = helper(left, p - 1) 和右子树 root.right = helper(p + 1, right)
  • 返回 helper(0, len(nums) - 1)

代码:

class Solution {
   
  int[
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值