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

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

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



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


本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 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。


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


目录
相关文章
|
3月前
Leetcode第21题(合并两个有序链表)
这篇文章介绍了如何使用非递归和递归方法解决LeetCode第21题,即合并两个有序链表的问题。
56 0
Leetcode第21题(合并两个有序链表)
|
3月前
|
存储 算法
【❤️算法笔记❤️】-每日一刷-21、合并两个有序链表
【❤️算法笔记❤️】-每日一刷-21、合并两个有序链表
117 0
|
24天前
|
存储 缓存 安全
只会“有序无序”?面试官嫌弃的List、Set、Map回答!
小米,一位热衷于技术分享的程序员,通过与朋友小林的对话,详细解析了Java面试中常见的List、Set、Map三者之间的区别,不仅涵盖了它们的基本特性,还深入探讨了各自的实现原理及应用场景,帮助面试者更好地准备相关问题。
56 20
|
5月前
|
Python
【Leetcode刷题Python】21. 合并两个有序链表
介绍了几种不同的方法来合并多个已排序的链表,包括暴力求解、使用小顶堆以及分而治之策略。
48 2
|
7月前
|
存储 算法 C语言
【数据结构与算法 刷题系列】合并两个有序链表
【数据结构与算法 刷题系列】合并两个有序链表
|
3月前
|
存储 算法 安全
HashMap常见面试题(超全面):实现原理、扩容机制、链表何时升级为红黑树、死循环
HashMap常见面试题:红黑树、散列表,HashMap实现原理、扩容机制,HashMap的jd1.7与jdk1.8有什么区别,寻址算法、链表何时升级为红黑树、死循环
|
5月前
|
算法
LeetCode第21题合并两个有序链表
该文章介绍了 LeetCode 第 21 题合并两个有序链表的解法,通过创建新链表,依次比较两个链表的头节点值,将较小的值插入新链表,直至其中一个链表遍历完,再将另一个链表剩余部分接到新链表后面,实现合并。
LeetCode第21题合并两个有序链表
|
6月前
【数据结构OJ题】合并两个有序链表
力扣题目——合并两个有序链表
45 8
【数据结构OJ题】合并两个有序链表
|
5月前
|
算法
【算法】合并两个有序链表(easy)——递归算法
【算法】合并两个有序链表(easy)——递归算法
【算法】合并两个有序链表(easy)——递归算法
|
5月前
|
存储 算法 Python
【面试题】合井K个升序链表
【面试题】合井K个升序链表
36 0

热门文章

最新文章