109. Convert Sorted List to Binary Search Tree

该题需要用一个递增的链表构建一个二叉树。数组的中位数为数的根节点,以中位数为分界,可以将数组分成左子数组以及右子数组,那么左边数组的中位数是左节点的值,右边数组的中位数为右节点的值,以此类推。

所以我们可以想到,首先需要将链表转换为数组,然后直接定位中位数的值为根节点的值,并通过递归的方法分别构造左子树以及右子树。

代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) { val = x; }
 7  * }
 8  */
 9 /**
10  * Definition for a binary tree node.
11  * public class TreeNode {
12  *     int val;
13  *     TreeNode left;
14  *     TreeNode right;
15  *     TreeNode(int x) { val = x; }
16  * }
17  */
18 class Solution {
19     public TreeNode sortedListToBST(ListNode head) {
20         if(head == null){
21             return null;
22         }
23         
24         ListNode temp = head;
25         int nodenum = 0;
26         while(temp != null){
27             temp = temp.next;
28             nodenum ++;
29         }
30         
31         int[] temparray = new int[nodenum];
32         temp = head;
33         
34         for(int i = 0 ; i < nodenum ; i++){
35             temparray[i] = temp.val;
36             temp = temp.next;
37         }
38         
39         TreeNode root = new TreeNode(0);
40         helper(root, temparray, 0, nodenum - 1);
41         
42         return root;
43     }
44     
45     private void helper(TreeNode res, int[] arr, int lindex, int rindex){
46         
47         int pos = (rindex - lindex + 1)%2 == 0 ? (rindex + lindex + 1)/2:(rindex + lindex)/2;
48         res.val = arr[pos];
49         
50         if(pos - 1  >= lindex){
51             res.left = new TreeNode(0);
52             helper(res.left, arr, lindex, pos - 1);
53         }
54         
55         if( rindex >= pos + 1){
56             res.right = new TreeNode(0);
57             helper(res.right, arr, pos + 1, rindex);
58         }
59     }
60 }

 

怎么才能不需要额外空间就能够实现二叉树的构建呢?参考了一下以下链接,

https://blog.csdn.net/worldwindjp/article/details/39722643

分别有自顶向下以及自底向上的构建方法。

贴上方法一的代码:

 1     public class Solution {  
 2         ListNode getLeftNodeFromList(ListNode head) {  
 3             ListNode next = head;  
 4             ListNode current = head;   
 5             ListNode pre = head;  
 6       
 7             while(next!=null) {  
 8                 next = next.next;  
 9                 if(next==null) {  
10                     break;  
11                 }  
12                 next = next.next;  
13                 if(next==null) {  
14                     break;  
15                 }  
16                 pre = head;  
17                 head = head.next;  
18             }  
19             return pre;  
20         }  
21           
22           
23         public TreeNode sortedListToBST(ListNode head) {  
24             if(head==null) {  
25                 return null;  
26             }  
27             if(head.next==null) {  
28                 return new TreeNode(head.val);  
29             }  
30               
31             ListNode left = getLeftNodeFromList(head);  
32             ListNode mid = left.next;  
33             TreeNode root = new TreeNode(mid.val);  
34             left.next     = null;  
35             root.left     = sortedListToBST(head);  
36             root.right    = sortedListToBST(mid.next);  
37             return root;  
38         }  
39     }  

不需要额外空间的关键在于能够找到在链表当中获取中位数的方法,主要思路为定义了两个指针,在遍历链表的时候,一个指针每次循环遍历两个节点,一个只是遍历一个,当遍历两个的指针为空的时候,另一个指针就会指向链表的中间节点。

利用这种思路,首先找出链表中中间节点的前一个节点,然后使用中间节点的值构造根节点;接着将链表分拆成左边的链表以及右边的链表,中间节点的前一个节点的next定义为null,那么中间节点的next就指向了右边的链表,以此类推。

贴上方法二的代码:

 1     public class Solution {  
 2         static ListNode currentHead = null;  
 3         TreeNode buildTree(int start, int end) {  
 4             if(start>end) {  
 5                 return null;  
 6             }  
 7             int mid = start + (end - start)/2;  
 8             TreeNode left = buildTree(start, mid-1);  
 9             TreeNode root = new TreeNode(currentHead.val);  
10             root.left = left;  
11             currentHead = currentHead.next;  
12             root.right = buildTree(mid + 1, end);  
13             return root;  
14         }  
15           
16         public TreeNode sortedListToBST(ListNode head) {  
17             if(head==null) {  
18                 return null;  
19             }  
20             currentHead = head;  
21             int len = 0;  
22             while(head!=null) {  
23                 len++;  
24                 head = head.next;  
25             }  
26               
27             return buildTree(0, len-1);  
28         }  
29     }  

方法二是先构造左子树,通过递归,首先找出链表第一个节点在树中的位置,找到后用链表节点的值构造树节点,接着寻找链表第二个节点在树中的位置,以此类推。

 

 

END

 

原文地址:https://www.cnblogs.com/sssysukww/p/8862971.html