題目:
給定一個單鏈表,其中的元素按升序排序,請將它轉化成平衡二叉搜索樹(BST)
示例:
給定的有序鏈表: [-10, -3, 0, 5, 9],
一個可能的答案是:[0, -3, 9, -10, null, 5],
0
/ \
-3 9
/ /
-10 5
思路:
- 先獲得鏈表的中間節點,作爲樹的根節點,並且將鏈表切斷爲左右兩個鏈表,根節點的左子樹爲左鏈表的中間節點,右子樹爲右鏈表的中間節點。接着就這樣進行遞歸的生成左右子樹。
代碼:
package com.company;
public class TestNo29 {
//定義單鏈表
static class ListNode{
int val;
ListNode next;
ListNode(int x){
val = x;
}
public String toString(){
if(this.next == null){
return String.valueOf(this.val);
}else{
return this.val + "->" + this.next.toString();
}
}
}
//定義樹節點
static class TreeNode{
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){
val = x;
}
}
public static void main(String[] args) {
//生成鏈表
ListNode head = new ListNode(0);
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(3);
ListNode node3 = new ListNode(4);
ListNode node4 = new ListNode(5);
ListNode node5 = new ListNode(9);
head.next = node1;
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
System.out.println(head);
TestNo29 t = new TestNo29();
System.out.println(t.sortedListToBST(head));
}
public TreeNode sortedListToBST(ListNode head) {
if(head == null){
return null;
}
//如果只有一個節點,那麼樹只有一個根節點
if(head.next == null){
return genTreeNode(head);
}
//獲取中間節點,生成樹的根部節點
ListNode mid = getMidAndCutList(head);
//產生樹的根節點
TreeNode root = genTreeNode(mid);
//產生樹根節點的左子樹
root.left = genTreeNode(head);
//產生樹根部節點的右邊子樹
root.right = genTreeNode(mid.next);
return root;
}
//產生新的樹節點
private TreeNode genTreeNode(ListNode node){
return node == null ? null : new TreeNode(node.val);
}
//得到鏈表的中間節點,並且從中間位置進行切斷
private ListNode getMidAndCutList(ListNode head){
if(head == null || head.next == null){
return head;
}
ListNode first = head;
ListNode second = head;
ListNode pre = new ListNode(0);
pre.next = head;
while (first!=null && first.next!=null){
first = first.next.next;
second = second.next;
pre= pre.next;
}
//通過pre指針將鏈表從中間進行切斷
pre.next = null;
return second;
}
}