0109. Convert Sorted List to Binary Search Tree (M)
Convert Sorted List to Binary Search Tree (M)
题目
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
Example:
Given the sorted linked list: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
0
/ \
-3 9
/ /
-10 5
题意
将一个有序链表转换成左右子树高度差不超过1的平衡二叉查找树。
思路
比较简单的方法是,将链表中的值存入数组中,接下来与 108. Convert Sorted Array to Binary Search Tree 一样进行二分递归。
直接用快慢指针可以一次遍历找到链表中的中位数:初始时快慢指针同时指向头结点,每次移动慢指针走1步、快指针走2步,当快指针无法继续走时慢指针正好指在中位数处。每次找到当前链表的中位数作为当前子树的根,以中位数为中心划分出左右链表,递归生成左右子树。
模拟中序遍历:很玄妙,利用了二叉查找树的中序遍历是递增序列的性质,具体还是看官方解答 - Approach 3: Inorder Simulation。
代码实现
Java
快慢指针
class Solution {
public TreeNode sortedListToBST(ListNode head) {
if (head == null) {
return null;
}
ListNode mid = findMid(head);
TreeNode x = new TreeNode(mid.val);
x.left = mid == head ? null : sortedListToBST(head);
x.right = sortedListToBST(mid.next);
return x;
}
private ListNode findMid(ListNode head) {
ListNode pre = null;
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
if (pre != null) {
pre.next = null;
}
return slow;
}
}
模拟中序遍历
class Solution {
private ListNode head;
public TreeNode sortedListToBST(ListNode head) {
this.head = head;
// 求出链表长度
int len = 0;
ListNode p = head;
while (p != null) {
len++;
p = p.next;
}
return sortedListToBST(0, len - 1);
}
private TreeNode sortedListToBST(int left, int right) {
if (left > right) {
return null;
}
int mid = (left + right) / 2;
TreeNode leftChild = sortedListToBST(left, mid - 1);
TreeNode root = new TreeNode(head.val);
root.left = leftChild;
head = head.next;
root.right = sortedListToBST(mid + 1, right);
return root;
}
}
JavaScript
/**
* @param {ListNode} head
* @return {TreeNode}
*/
var sortedListToBST = function (head) {
const nums = []
while (head) {
nums.push(head.val)
head = head.next
}
return dfs(nums, 0, nums.length - 1)
}
var dfs = function (nums, left, right) {
if (left > right) return null
const mid = Math.trunc((right - left) / 2) + left
const root = new TreeNode(nums[mid])
root.left = dfs(nums, left, mid - 1)
root.right = dfs(nums, mid + 1, right)
return root
}
分类:
LeetCode
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 上周热点回顾(1.20-1.26)