問題描述:
給定一個單鏈表,其中的元素按升序排序,將其轉換爲高度平衡的二叉搜索樹。
本題中,一個高度平衡二叉樹是指一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 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