首页 > 其他分享 >109. 有序链表转换二叉搜索树【二叉树】

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

时间:2024-10-18 09:16:49浏览次数:3  
标签:head midNode Next 链表 109 二叉树 二叉 节点

文章目录

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

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

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

平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1

示例 1:
在这里插入图片描述

输入: head = [-10,-3,0,5,9]
输出: [0,-3,9,-10,null,5]
解释: 一个可能的答案是[0,-3,9,-10,null,5],它表示所示的高度平衡的二叉搜索树。

示例 2:

输入: head = []
输出: []

提示:

  • head 中的节点数在[0, 2 * 10^4] 范围内
  • -10^5 <= Node.val <= 10^5

解题思路

寻找到链表的中间节点作为根节点,然后递归构建左右子树

  1. 每次取链表中间节点作为根节点,左右两边元素相差不会大于1,会是平衡的
  2. 链表本身就是升序排序,所以构建后会是二叉搜索树,
  3. 综上,符合题目要求的平衡二叉搜索树要求

需要注意的是递归终止条件,链表空或者只有一个元素的时候就可以终止递,往上归了,上层用root.Leftroot.Right指针接住。

Go代码

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func sortedListToBST(head *ListNode) *TreeNode {
    // 寻找到链表的中间节点作为根节点,然后递归构建左右子树
    // 每次取链表中间节点作为根节点,左右两边元素相差不会大于1,会是平衡的
    // 链表本身就是升序排序,所以构建后会是二叉搜索树,
    // 综上,符合题目要求的平衡二叉搜索树要求
    if head == nil {
        return nil
    }
    if head.Next == nil {
        return &TreeNode{Val:head.Val}
    }
    // 寻找链表中间节点
    midNode := findMidNodeOfList(head)
    // 构造根节点
    root := &TreeNode{Val:midNode.Val}
    // 切割链表为左右两部分,并递归构建左右子树
    rightList := midNode.Next // 右边的链表从midNode下个节点开始,直到最后
    midNode.Next = nil // rightList记录了下个链表的开始,midNode的Next可以释放了
    dummy := &ListNode{}
    dummy.Next = head
    cur := dummy
    for  cur.Next != midNode{
        cur = cur.Next
    }
    cur.Next = nil // 左边的链表head开始,到midNode为止,不包含midNode
    root.Left = sortedListToBST(head)
    root.Right = sortedListToBST(rightList)

    return root
}

func findMidNodeOfList(head *ListNode) *ListNode {
    // 经典双指针做法,快指针一次走两步,慢指针一次走一步,快指针到最后一个节点,慢指针刚好指着中间节点
    slow,fast := head,head
    for fast != nil && fast.Next != nil {
        fast = fast.Next.Next
        slow = slow.Next
    }
    return slow
}

在这里插入图片描述

标签:head,midNode,Next,链表,109,二叉树,二叉,节点
From: https://blog.csdn.net/YouMing_Li/article/details/142992623

相关文章

  • 七、二叉树之链式结构(递归)
    一、前序:前面章节所说二叉树的结构其实是递归的,为什么这样说呢?根节点有左右子树,根节点的左右孩子又有左右子树,以此类推,直到叶子节点,它的左右子树为NULL,开始返回。所以,我们把它分成一个又一个的子树来分析。因此,它的结构是递归的。因为一开始接触二叉树,还不是熟悉,我们先来手动......
  • 力扣面试题02.07.链表相交
    题目链接:面试题02.07.链表相交-力扣(LeetCode)给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。图示两个链表在节点 c1 开始相交:题目数据 保证 整个链式结构中不存在环。注意,函数返回结果......
  • 力扣142.环形链表II
    题目链接:142.环形链表II-力扣(LeetCode)给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数 pos 来表示......
  • 【数据结构】之链表详解
    链表是一种常用的数据结构,它是一种线性数据结构,但与数组不同,它并非连续存储数据,而是通过指针将数据节点连接起来。每个节点都包含数据域和指向下一个节点的指针域。这种结构赋予链表独特的优势和局限性,使其在某些场景下优于数组,在另一些场景下则相对逊色。本文将深入探讨链表,包......
  • Java数据结构二叉树面试题精华(画图详解)
    前言:    针对二叉树,因为涉及到递归,需要跟多的练习强化递归的思想,其中也包括需要画图理解一些想不通的问题来提升自己!    一下面这些题为例,一起来提升自己的逻辑思维能力!(可能其中一些题已经写过,但是希望能再写一遍有助于提高代码能力)相同的树:      ......
  • 翻转链表常用写法
    翻转链表常用写法循环写法classSolution{public:ListNode*reverseList(ListNode*head){ListNode*prev=nullptr,*next=nullptr,*now=head;while(now){next=now->next;now->next=prev;prev=......
  • 手撸二叉树——AVL平衡二叉树
    还记得上一篇中我们遗留的问题吗?我们再简要回顾一下,现在有一颗空的二叉查找树,我们分别插入1,2,3,4,5,五个节点,那么得到的树是什么样子呢?这个不难想象,二叉树如下:树的高度是4,并且数据结构上和链表没有区别,查找性能也和链表一致。如果我们将树的结构改变一下呢?比如改成下面的树结构,那......
  • 树、森林与二叉树的转换
    一、引言与问题引出        在计算机科学的数据结构领域中,树、森林与二叉树之间的转换具有重要意义。在实际研究过程中,我们常常会发现树的结构过于复杂,而二叉树相对简单。例如,普通的树形结构使用程序语言描述起来相对复杂,而二叉树则相对容易。一颗普通的树可以通过孩......
  • 24. 两两交换链表中的节点
    给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。示例1:输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]输出:[1]解题思路:1.递归方法实现节点对的交换......
  • 代码随想录|二叉树part 03
    求普通二叉树的节点数量要点:将子节点的个数记录到父节点,使用后序遍历classSolution{public:intmaxDepth(TreeNode*root){if(root==NULL)return0;intleft1=maxDepth(root->left);intright1=maxDepth(root->right);intnum=......