经典面试题:将有序数组、有序链表转换成平衡二叉树

简介: 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

将有序数组转换成平衡二叉树



将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。


本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。


示例:

给定有序数组: [-10,-3,0,5,9],


一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:

0
     / \
   -3   9
   /   /
 -10  5


分析


对于二叉平衡树来说,我们知道它的中序序列是一个升序序列,刚好和我们的给定的升序数组是一致的。而数组反向构造一个二叉平衡树,如果从左向右一个个构造、旋转那样的话代价太大了,所以这道题我们根据数组的特征去构造一棵二叉平衡树。


二叉平衡树的左右高度之差小于等于1,那么我们每次按照这个策略构造即可完成一个二叉平衡树:每次选取待构造的中间节点当成根节点,然后递归的将左右两个区域按照同样方法构造。


20210124142621905.png


具体实现的代码为:


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
   public TreeNode sortedArrayToBST(int[] nums) {
    return sortedArrayToBST(nums,0,nums.length-1);
    }
  private TreeNode sortedArrayToBST(int[] nums, int start,int end) {
    if(nums.length==0||start>end)
      return null;
    int mid=(start+end)/2;
    TreeNode node=new TreeNode(nums[mid]);
    node.left=sortedArrayToBST(nums, start, mid-1);
    node.right=sortedArrayToBST(nums, mid+1, end);
    return node;
  }
}


将有序链表转换为二叉平衡树



给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。


示例:


给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
      0
     / \
   -3   9
   /   /
 -10  5


分析:

这道题的核心思路和有序数组的转换成平衡二叉树差不多,但是链表的弱点就是查询效率,当然你可以先枚举一遍链表然后转换成数组转换成二叉平衡树的问题,和上一题的思路相同,但是这里的话就是用一个快慢指针进行查找。


20210124142841225.png


当然,每次找到中间节点的时候同样需要将链表分成两部分,这样我事先将慢指针设置一个前驱节点在操作的时候更容易拆分成两个部分。


20210124142911894.png


具体的代码为:


 /**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        if(head==null)
            return  null;
        if(head.next==null)
            return  new TreeNode(head.val);
        ListNode fast=head;
        ListNode slow=new ListNode(0);
        slow.next=head;
        while(fast!=null&&fast.next!=null)
        {
            fast=fast.next.next;
            slow=slow.next;
        }
        TreeNode node=new TreeNode(slow.next.val);
        node.right=sortedListToBST(slow.next.next);
        slow.next=null;
        node.left=sortedListToBST(head);
        return  node;
    }
}


原创不易,bigsai请你帮两件事帮忙一下:


star支持一下, 您的肯定是我在平台创作的源源动力。


微信搜索「bigsai」,关注我的公众号,不仅免费送你电子书,我还会第一时间在公众号分享知识技术。加我还可拉你进力扣打卡群一起打卡LeetCode。


记得关注、咱们下次再见!


目录
相关文章
|
1月前
|
算法
LeetCode刷题---21.合并两个有序链表(双指针)
LeetCode刷题---21.合并两个有序链表(双指针)
|
3月前
|
安全 Java 编译器
【面试问题】说说原子性、可见性、有序性?
【1月更文挑战第27天】【面试问题】说说原子性、可见性、有序性?
LeetCode | 21. 合并两个有序链表
LeetCode | 21. 合并两个有序链表
|
2月前
|
存储 算法
头歌:第1关:有序单链表的插入操作
头歌:第1关:有序单链表的插入操作
102 0
|
4天前
【力扣】21. 合并两个有序链表
【力扣】21. 合并两个有序链表
|
1月前
|
存储 算法
【数据结构与算法】【腾讯阿里链表面试题】算法题--链表易懂版讲解
【数据结构与算法】【腾讯阿里链表面试题】算法题--链表易懂版讲解
|
1月前
|
C语言
反转链表、链表的中间结点、合并两个有序链表【LeetCode刷题日志】
反转链表、链表的中间结点、合并两个有序链表【LeetCode刷题日志】
|
1月前
|
存储 算法 Java
【数据结构与算法】2、链表(简单模拟 Java 中的 LinkedList 集合,反转链表面试题)
【数据结构与算法】2、链表(简单模拟 Java 中的 LinkedList 集合,反转链表面试题)
42 0
|
2月前
Leecode之合并两个有序链表
Leecode之合并两个有序链表
|
2月前
|
存储 算法
头歌【第2关:有序单链表中值相同的多余结点的删除操作】
头歌【第2关:有序单链表中值相同的多余结点的删除操作】
37 0