问题描述:
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree
思路1:
先将单向链表转换为数组。再找出中点索引。前半部分转换为左子树,后半部分转换成右子树。
Python版本:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def chainTableToArray(self, head):
array = []
while head:
array.append(head.val)
head = head.next
return array
def sortedListToBST(self, head):
"""
:type head: ListNode
:rtype: TreeNode
"""
array = self.chainTableToArray(head)
def arrayToBST(l,r):
if(l>r):
return None
mid = (l+r)/2
currentNode = TreeNode(array[mid])
if l==r:
return currentNode
currentNode.left = arrayToBST(0,mid-1)
currentNode.right = arrayToBST(mid+1,r)
return currentNode
return arrayToBST(0,len(array)-1)
Java版本:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode sortedListToBST(ListNode head) {
ArrayList<Integer> list = new ArrayList<>();
while (head!=null){
list.add(head.val);
head=head.next;
}
if (list.size()==0) return null;
return sortedArrayToBST(list);
}
public TreeNode sortedArrayToBST(List<Integer> nums) {
int index = nums.size() / 2;
TreeNode treeNode = new TreeNode(nums.get(index));
if (index > 0) {
treeNode.left = sortedArrayToBST(nums.subList(0, index));
}
if (nums.size() - index - 1 > 0) {
treeNode.right = sortedArrayToBST(nums.subList(index + 1, nums.size()));
}
return treeNode;
}
}
思路2:
对于这种中点问题一个常见的处理思路就是通过快慢指针。我们可以建立两个指针slow
和fast
,其中一个slow=slow.next
,另外一个fast=fast.next.next
,这样当我们的fast
指向最后节点的时候,slow
一定是指向中间节点的。
但是有一个问题是:我们无法知道slow
的前一个位置了。怎么办?我们可以让fast
提前跑。fast
提前跑后,slow.next
就变成了mid
的位置。
python版本:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def sortedListToBST(self, head):
"""
:type head: ListNode
:rtype: TreeNode
"""
if not head:
return
if not head.next:
return TreeNode(head.val)
slow, fast = head, head.next.next # fast
while fast and fast.next:
slow = slow.next
fast = fast.next.next
tmp = slow.next
slow.next = None
res = TreeNode(tmp.val)
res.left = self.sortedListToBST(head)
res.right = self.sortedListToBST(tmp.next)
return res